diff options
author | Oliver Smith <osmith@sysmocom.de> | 2024-02-20 12:06:53 +0100 |
---|---|---|
committer | Oliver Smith <osmith@sysmocom.de> | 2024-02-21 13:06:04 +0100 |
commit | 2a0d37cb1db9d66301628db124aba8c0d496769f (patch) | |
tree | 5a331526e0984f8bd32ab10e58b880c28f4246af | |
parent | f3d541e353e6aa59a9333b92a75893395fb1908f (diff) |
gtp_new: deduplicate create_and_bind_socket code
Change-Id: Iff3cfdfb0c08033d869c51499754b3416c71732b
-rw-r--r-- | gtp/gsn.c | 122 |
1 files changed, 51 insertions, 71 deletions
@@ -423,11 +423,45 @@ free_filename: talloc_free(filename); } -int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen, - int mode) +static int create_and_bind_socket(const char *name, struct gsn_t *gsn, int *fd, int domain, + const struct in_addr *listen, int port) { struct sockaddr_in addr; + int type = SOCK_DGRAM; + int protocol = 0; + + *fd = socket(domain, type, protocol); + + if (*fd < 0) { + rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET); + LOGP(DLGTP, LOGL_ERROR, + "%s socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n", + name, domain, type, protocol, strerror(errno)); + return -errno; + } + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = domain; + addr.sin_addr = *listen; + addr.sin_port = htons(port); +#if defined(__FreeBSD__) || defined(__APPLE__) + addr.sin_len = sizeof(addr); +#endif + + if (bind(*fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + rate_ctr_inc2(gsn->ctrg, GSN_CTR_ERR_SOCKET); + LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr, + "%s bind(fd=%d) failed: Error = %s\n", + name, *fd, strerror(errno)); + return -errno; + } + + return 0; +} +int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen, + int mode) +{ LOGP(DLGTP, LOGL_NOTICE, "GTP: gtp_newgsn() started at %s\n", inet_ntoa(*listen)); *gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */ @@ -467,89 +501,35 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen, (*gsn)->cb_data_ind = 0; /* Store function parameters */ + /* Same IP for user traffic and signalling */ (*gsn)->gsnc = *listen; (*gsn)->gsnu = *listen; (*gsn)->mode = mode; - /* Create GTP version 0 socket */ - if (((*gsn)->fd0 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP(DLGTP, LOGL_ERROR, - "GTPv0 socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n", - AF_INET, SOCK_DGRAM, 0, strerror(errno)); - return -errno; - } + (*gsn)->fd0 = -1; + (*gsn)->fd1c = -1; + (*gsn)->fd1u = -1; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = *listen; /* Same IP for user traffic and signalling */ - addr.sin_port = htons(GTP0_PORT); -#if defined(__FreeBSD__) || defined(__APPLE__) - addr.sin_len = sizeof(addr); -#endif - - if (bind((*gsn)->fd0, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr, - "bind(fd0=%d) failed: Error = %s\n", - (*gsn)->fd0, strerror(errno)); - return -errno; - } + /* Create GTP version 0 socket */ + if (create_and_bind_socket("GTPv0", *gsn, &(*gsn)->fd0, AF_INET, listen, GTP0_PORT) < 0) + goto error; /* Create GTP version 1 control plane socket */ - if (((*gsn)->fd1c = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP(DLGTP, LOGL_ERROR, - "GTPv1 control plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n", - AF_INET, SOCK_DGRAM, 0, strerror(errno)); - return -errno; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = *listen; /* Same IP for user traffic and signalling */ - addr.sin_port = htons(GTP1C_PORT); -#if defined(__FreeBSD__) || defined(__APPLE__) - addr.sin_len = sizeof(addr); -#endif - - if (bind((*gsn)->fd1c, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr, - "bind(fd1c=%d) failed: Error = %s\n", - (*gsn)->fd1c, strerror(errno)); - return -errno; - } + if (create_and_bind_socket("GTPv1 control plane", *gsn, &(*gsn)->fd1c, AF_INET, listen, GTP1C_PORT) < 0) + goto error; /* Create GTP version 1 user plane socket */ - if (((*gsn)->fd1u = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP(DLGTP, LOGL_ERROR, - "GTPv1 user plane socket(domain=%d, type=%d, protocol=%d) failed: Error = %s\n", - AF_INET, SOCK_DGRAM, 0, strerror(errno)); - return -errno; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr = *listen; /* Same IP for user traffic and signalling */ - addr.sin_port = htons(GTP1U_PORT); -#if defined(__FreeBSD__) || defined(__APPLE__) - addr.sin_len = sizeof(addr); -#endif - - if (bind((*gsn)->fd1u, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - rate_ctr_inc2((*gsn)->ctrg, GSN_CTR_ERR_SOCKET); - LOGP_WITH_ADDR(DLGTP, LOGL_ERROR, addr, - "bind(fd1u=%d) failed: Error = %s\n", - (*gsn)->fd1u, strerror(errno)); - return -errno; - } + if (create_and_bind_socket("GTPv1 user plane", *gsn, &(*gsn)->fd1u, AF_INET, listen, GTP1U_PORT) < 0) + goto error; /* Start internal queue timer */ gtp_queue_timer_start(*gsn); return 0; +error: + gtp_free(*gsn); + *gsn = NULL; + return -1; } int gtp_free(struct gsn_t *gsn) |