osmith has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ggsn/+/36030?usp=email )
Change subject: gtp_new: deduplicate create_and_bind_socket code ......................................................................
gtp_new: deduplicate create_and_bind_socket code
Change-Id: Iff3cfdfb0c08033d869c51499754b3416c71732b --- M gtp/gsn.c 1 file changed, 60 insertions(+), 71 deletions(-)
Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified pespin: Looks good to me, but someone else must approve
diff --git a/gtp/gsn.c b/gtp/gsn.c index 8b3ea3a..eb15eaf 100644 --- a/gtp/gsn.c +++ b/gtp/gsn.c @@ -423,11 +423,45 @@ talloc_free(filename); }
+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) { - struct sockaddr_in addr; - 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 @@ (*gsn)->cb_data_ind = 0;
/* Store function parameters */ + /* Same IP for user traffic and signalling */ (*gsn)->gsnc = *listen; (*gsn)->gsnu = *listen; (*gsn)->mode = mode;
+ (*gsn)->fd0 = -1; + (*gsn)->fd1c = -1; + (*gsn)->fd1u = -1; + /* 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; - } - - 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; - } + 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)