[MERGED] osmo-ggsn[master]: libgtp: Avoid extra memcpy() in gtp_data_req() by using send...

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/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Sun Sep 24 12:55:25 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: libgtp: Avoid extra memcpy() in gtp_data_req() by using sendmsg()
......................................................................


libgtp: Avoid extra memcpy() in gtp_data_req() by using sendmsg()

Adresses two "TODO Should be avoided" comments about an extra memcpy()
before sendto() that can be replaced by a single sendmsg() call with an
iovec array: 1 record for the GTP header + 1 record for the user payload.

Change-Id: Ie332a6b15972330fcf540753898eb84ecb84fe24
---
M gtp/gtp.c
1 file changed, 20 insertions(+), 29 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/gtp/gtp.c b/gtp/gtp.c
index 27a07b1..e41e692 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -3146,20 +3146,34 @@
 {
 	union gtp_packet packet;
 	struct sockaddr_in addr;
+	struct msghdr msgh;
+	struct iovec iov[2];
 	int fd;
-	int length;
 
+	/* prepare destination address */
 	memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 #if defined(__FreeBSD__) || defined(__APPLE__)
 	addr.sin_len = sizeof(addr);
 #endif
-
 	memcpy(&addr.sin_addr, pdp->gsnru.v, pdp->gsnru.l);	/* TODO range check */
+
+	/* prepare msghdr */
+	memset(&msgh, 0, sizeof(msgh));
+	msgh.msg_name = &addr;
+	msgh.msg_namelen = sizeof(addr);
+	msgh.msg_iov = iov;
+	msgh.msg_iovlen = ARRAY_SIZE(iov);
+
+	/* prepare iovectors */
+	iov[0].iov_base = &packet;
+	/* iov[0].iov_len is not known here yet */
+	iov[1].iov_base = pack;
+	iov[1].iov_len = len;
 
 	if (pdp->version == 0) {
 
-		length = GTP0_HEADER_SIZE + len;
+		iov[0].iov_len = GTP0_HEADER_SIZE;
 		addr.sin_port = htons(GTP0_PORT);
 		fd = gsn->fd0;
 
@@ -3168,19 +3182,9 @@
 		packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
 		packet.gtp0.h.flow = hton16(pdp->flru);
 		packet.gtp0.h.tid = htobe64(pdp_gettid(pdp->imsi, pdp->nsapi));
-
-		if (len > sizeof(union gtp_packet) - sizeof(struct gtp0_header)) {
-			gsn->err_memcpy++;
-			LOGP(DLGTP, LOGL_ERROR,
-				"Memcpy failed: %u > %zu\n", len,
-				sizeof(union gtp_packet) -
-				sizeof(struct gtp0_header));
-			return EOF;
-		}
-		memcpy(packet.gtp0.p, pack, len);	/* TODO Should be avoided! */
 	} else if (pdp->version == 1) {
 
-		length = GTP1_HEADER_SIZE_LONG + len;
+		iov[0].iov_len = GTP1_HEADER_SIZE_LONG;
 		addr.sin_port = htons(GTP1U_PORT);
 		fd = gsn->fd1u;
 
@@ -3189,18 +3193,6 @@
 					       GTP1_HEADER_SIZE_LONG);
 		packet.gtp1l.h.seq = hton16(pdp->gtpsntx++);
 		packet.gtp1l.h.tei = hton32(pdp->teid_gn);
-
-		if (len >
-		    sizeof(union gtp_packet) -
-		    sizeof(struct gtp1_header_long)) {
-			gsn->err_memcpy++;
-			LOGP(DLGTP, LOGL_ERROR,
-				"Memcpy failed: %u > %zu\n", len,
-				sizeof(union gtp_packet) -
-				sizeof(struct gtp0_header));
-			return EOF;
-		}
-		memcpy(packet.gtp1l.p, pack, len);	/* TODO Should be avoided! */
 	} else {
 		LOGP(DLGTP, LOGL_ERROR, "Unknown version: %d\n", pdp->version);
 		return EOF;
@@ -3211,11 +3203,10 @@
 		return -1;
 	}
 
-	if (sendto(fd, &packet, length, 0,
-		   (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+	if (sendmsg(fd, &msgh, 0) < 0) {
 		gsn->err_sendto++;
 		LOGP(DLGTP, LOGL_ERROR,
-			"Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
+			"sendmsg(fd=%d, msg=%lx, len=%d) failed: Error = %s\n", fd,
 			(unsigned long)&packet, GTP0_HEADER_SIZE + len,
 			strerror(errno));
 		return EOF;

-- 
To view, visit https://gerrit.osmocom.org/4033
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ie332a6b15972330fcf540753898eb84ecb84fe24
Gerrit-PatchSet: 1
Gerrit-Project: osmo-ggsn
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list