[PATCH 13/15] gtphub: split gtp_relay() in r/w funcs

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Neels Hofmeyr nhofmeyr at sysmocom.de
Thu Oct 15 22:13:57 UTC 2015


diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index 73e7c02..9f3e021 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -265,6 +265,9 @@ static void gtp_decode(const uint8_t *data, int data_len, struct gtp_packet_desc
 
 	validate_gtp_header(res);
 
+	if (res->rc > 0)
+		LOG("Valid GTP header (v%d)\n", res->version);
+
 	if (res->rc == GTP_RC_TINY)
 		LOG("tiny: no IEs in this GTP packet\n");
 
@@ -441,23 +444,20 @@ static int gtphub_gtp_bind_init(struct gtphub_bind *b,
 }
 
 /* Recv datagram from from->fd, optionally write sender's address to *from_addr
- * and *from_addr_len, parse datagram as GTP, and forward on to to->fd using
- * *to_addr. to_addr may be NULL, if an address is set on to->fd. */
-static int gtp_relay(struct osmo_fd *from,
-		     struct sockaddr_storage *from_addr,
-		     socklen_t *from_addr_len,
-		     struct osmo_fd *to,
-		     struct sockaddr_storage *to_addr,
-		     socklen_t to_addr_len)
+ * and *from_addr_len. Return the number of bytes read. */
+/* Send datagram to to->fd using *to_addr. to_addr may be NULL, if an address
+ * is set on to->fd. */
+static int gtphub_read(struct osmo_fd *from,
+		       struct sockaddr_storage *from_addr,
+		       socklen_t *from_addr_len,
+		       uint8_t *buf, size_t buf_len)
 {
-	static uint8_t buf[4096];
-
 	/* recvfrom requires the available length to be set in *from_addr_len. */
 	if (from_addr_len && from_addr)
 		*from_addr_len = sizeof(*from_addr);
 
 	errno = 0;
-	ssize_t received = recvfrom(from->fd, buf, sizeof(buf), 0,
+	ssize_t received = recvfrom(from->fd, buf, buf_len, 0,
 				    (struct sockaddr*)from_addr, from_addr_len);
 	/* TODO use recvmsg and get a MSG_TRUNC flag to make sure the message
 	 * is not truncated. Then maybe reduce buf's size. */
@@ -465,7 +465,7 @@ static int gtp_relay(struct osmo_fd *from,
 	if (received <= 0) {
 		if (errno != EAGAIN)
 			LOGERR("error: %s\n", strerror(errno));
-		return -errno;
+		return 0;
 	}
 
 	if (from_addr) {
@@ -474,25 +474,20 @@ static int gtp_relay(struct osmo_fd *from,
 
 	if (received <= 0) {
 		LOGERR("error: %s\n", strerror(errno));
-		return -EINVAL;
+		return 0;
 	}
 
-	/* insert magic here */
 	LOG("Received %d\n%s\n", (int)received, osmo_hexdump(buf, received));
+	return received;
+}
 
-	struct gtp_packet_desc p;
-	gtp_decode(buf, received, &p);
-
-	if (p.rc > 0)
-		LOG("Valid GTP header (v%d)\n", p.version);
-#if 0
-	else
-		// error has been logged
-		return 0;
-#endif
-
+static int gtphub_write(struct osmo_fd *to,
+			struct sockaddr_storage *to_addr,
+			socklen_t to_addr_len,
+			uint8_t *buf, size_t buf_len)
+{
 	errno = 0;
-	ssize_t sent = sendto(to->fd, buf, received, 0,
+	ssize_t sent = sendto(to->fd, buf, buf_len, 0,
 			      (struct sockaddr*)to_addr, to_addr_len);
 
 	if (to_addr) {
@@ -504,8 +499,8 @@ static int gtp_relay(struct osmo_fd *from,
 		return -EINVAL;
 	}
 
-	if (sent != received)
-		LOGERR("sent(%d) != received(%d)\n", (int)sent, (int)received);
+	if (sent != buf_len)
+		LOGERR("sent(%d) != data_len(%d)\n", (int)sent, (int)buf_len);
 	else
 		LOG("%d b ok\n", (int)sent);
 
@@ -530,9 +525,23 @@ int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what)
 		return 0;
 	}
 
-	return gtp_relay(from_ggsns_ofd, NULL, NULL,
-			 &hub->to_sgsns[port_idx].ofd,
-			 &sgsn->addr.a, sgsn->addr.l);
+	static uint8_t buf[4096];
+	size_t received = gtphub_read(from_ggsns_ofd, NULL, NULL,
+				      buf, sizeof(buf));
+	if (received < 1)
+		return 0;
+
+	static struct gtp_packet_desc p;
+	gtp_decode(buf, received, &p);
+
+#if 0
+	if (p.rc <= 0)
+		return 0;
+#endif
+
+	return gtphub_write(&hub->to_sgsns[port_idx].ofd,
+			    &sgsn->addr.a, sgsn->addr.l,
+			    (uint8_t*)p.data, p.data_len);
 }
 
 int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what)
@@ -560,9 +569,23 @@ int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what)
 	if (!sgsn)
 		sgsn = gtphub_peer_new(&hub->to_sgsns[port_idx]);
 
-	return gtp_relay(from_sgsns_ofd, &sgsn->addr.a, &sgsn->addr.l,
-			 &hub->to_ggsns[port_idx].ofd,
-			 &ggsn->addr.a, ggsn->addr.l);
+	static uint8_t buf[4096];
+	size_t received = gtphub_read(from_sgsns_ofd, &sgsn->addr.a, &sgsn->addr.l,
+				      buf, sizeof(buf));
+	if (received < 1)
+		return 0;
+
+	static struct gtp_packet_desc p;
+	gtp_decode(buf, received, &p);
+
+#if 0
+	if (p.rc <= 0)
+		return 0;
+#endif
+
+	return gtphub_write(&hub->to_ggsns[port_idx].ofd,
+			    &ggsn->addr.a, ggsn->addr.l,
+			    (uint8_t*)p.data, p.data_len);
 }
 
 int gtphub_init(struct gtphub *hub, struct gtphub_cfg *cfg)
-- 
2.1.4




More information about the OpenBSC mailing list