aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Smith <osmith@sysmocom.de>2024-02-20 12:06:53 +0100
committerOliver Smith <osmith@sysmocom.de>2024-02-21 13:06:04 +0100
commit2a0d37cb1db9d66301628db124aba8c0d496769f (patch)
tree5a331526e0984f8bd32ab10e58b880c28f4246af
parentf3d541e353e6aa59a9333b92a75893395fb1908f (diff)
gtp_new: deduplicate create_and_bind_socket code
-rw-r--r--gtp/gsn.c122
1 files changed, 51 insertions, 71 deletions
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 @@ 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)