gtphub: fix User plane decoding, add unit test.

Split decoding return code GTP_RC_PDU in GTP_RC_PDU_C and GTP_RC_PDU_U.
Don't do IEs in GTP_RC_PDU_U.

Add a unit test for User plane data, expected to fail (nonstandard port case).

In gtphub_test.c, tweak logging so that it is easily visible which test
produced which output. Also add the global resolved_sgsn_addr and ggsn_sender,
symmetrically to resolved_ggsn_add and sgsn_sender.

Sponsored-by: On-Waves ehi
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index f24fc04..9a29cc0 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -66,7 +66,8 @@
 enum gtp_rc {
 	GTP_RC_UNKNOWN = 0,
 	GTP_RC_TINY = 1,    /* no IEs (like ping/pong) */
-	GTP_RC_PDU = 2,     /* a real packet with IEs */
+	GTP_RC_PDU_C = 2,     /* a real packet with IEs */
+	GTP_RC_PDU_U = 3,     /* a real packet with User data */
 
 	GTP_RC_TOOSHORT = -1,
 	GTP_RC_UNSUPPORTED_VERSION = -2,
@@ -176,7 +177,7 @@
 
 static int gsn_addr_get(struct gsn_addr *gsna, const struct gtp_packet_desc *p, int idx)
 {
-	if (p->rc != GTP_RC_PDU)
+	if (p->rc != GTP_RC_PDU_C)
 		return -1;
 
 	unsigned int len;
@@ -191,7 +192,7 @@
 
 static int gsn_addr_put(const struct gsn_addr *gsna, struct gtp_packet_desc *p, int idx)
 {
-	if (p->rc != GTP_RC_PDU)
+	if (p->rc != GTP_RC_PDU_C)
 		return -1;
 
 	int ie_idx;
@@ -251,7 +252,7 @@
 
 	LOG("GTP v0 TID = %" PRIu64 "\n", pheader->tid);
 	p->header_len = GTP0_HEADER_SIZE;
-	p->rc = GTP_RC_PDU;
+	p->rc = GTP_RC_PDU_C;
 }
 
 /* Validate GTP version 1 data, and update p->rc with the result, as well as
@@ -306,7 +307,7 @@
 		return;
 	}
 
-	p->rc = GTP_RC_PDU;
+	p->rc = GTP_RC_PDU_C;
 	p->header_len = GTP1_HEADER_SIZE_LONG;
 }
 
@@ -449,7 +450,12 @@
 
 	LOG("Valid GTP header (v%d)\n", res->version);
 
-	if (res->rc != GTP_RC_PDU) {
+	if (from_plane_idx == GTPH_PLANE_USER) {
+		res->rc = GTP_RC_PDU_U;
+		return;
+	}
+
+	if (res->rc != GTP_RC_PDU_C) {
 		LOG("no IEs in this GTP packet\n");
 		return;
 	}
@@ -458,6 +464,7 @@
 			 (void*)(data + res->header_len),
 			 res->data_len - res->header_len) != 0) {
 		res->rc = GTP_RC_INVALID_IE;
+		LOGERR("INVALID: cannot decode IEs. Dropping GTP packet.\n");
 		return;
 	}
 
@@ -708,10 +715,6 @@
 						  const char *apn_ni_str);
 int gtphub_ares_init(struct gtphub *hub);
 
-static struct gtphub_peer_port *gtphub_port_find(const struct gtphub_bind *bind,
-						 const struct gsn_addr *addr,
-						 uint16_t port);
-
 static void gtphub_zero(struct gtphub *hub)
 {
 	ZERO_STRUCT(hub);
@@ -1377,7 +1380,9 @@
 				 struct osmo_fd **to_ofd,
 				 struct osmo_sockaddr *to_addr)
 {
-	LOG("<- rx from GGSN %s\n", osmo_sockaddr_to_str(from_addr));
+	LOG("<- rx %s from GGSN %s\n",
+	    gtphub_plane_idx_names[plane_idx],
+	    osmo_sockaddr_to_str(from_addr));
 
 	static struct gtp_packet_desc p;
 	gtp_decode(buf, received, plane_idx, &p);
@@ -1421,7 +1426,8 @@
 	 * this GGSN. If we don't have an entry, the GGSN has nothing to tell
 	 * us about. */
 	if (!ggsn) {
-		LOGERR("Invalid GGSN peer. Dropping packet.\n");
+		LOGERR("Dropping packet: unknown GGSN peer: %s\n",
+		       osmo_sockaddr_to_str(from_addr));
 		return -1;
 	}
 
@@ -1466,6 +1472,9 @@
 	osmo_sockaddr_copy(to_addr, &sgsn->sa);
 
 	*reply_buf = (uint8_t*)p.data;
+
+	LOG("<-- Forward to SGSN: %d bytes to %s\n",
+	    (int)received, osmo_sockaddr_to_str(to_addr));
 	return received;
 }
 
@@ -1511,7 +1520,9 @@
 				 struct osmo_fd **to_ofd,
 				 struct osmo_sockaddr *to_addr)
 {
-	LOG("-> rx from SGSN %s\n", osmo_sockaddr_to_str(from_addr));
+	LOG("-> rx %s from SGSN %s\n",
+	    gtphub_plane_idx_names[plane_idx],
+	    osmo_sockaddr_to_str(from_addr));
 
 	static struct gtp_packet_desc p;
 	gtp_decode(buf, received, plane_idx, &p);
@@ -1574,7 +1585,8 @@
 
 	if (!sgsn) {
 		/* This could theoretically happen for invalid address data or somesuch. */
-		LOGERR("Invalid SGSN peer. Dropping packet.\n");
+		LOGERR("Dropping packet: invalid SGSN peer: %s\n",
+		       osmo_sockaddr_to_str(from_addr));
 		return -1;
 	}
 	LOG("SGSN peer: %s\n", gtphub_port_str(sgsn));
@@ -1635,6 +1647,9 @@
 	osmo_sockaddr_copy(to_addr, &ggsn->sa);
 
 	*reply_buf = (uint8_t*)p.data;
+
+	LOG("--> Forward to GGSN: %d bytes to %s\n",
+	    (int)received, osmo_sockaddr_to_str(to_addr));
 	return received;
 }
 
@@ -1979,7 +1994,13 @@
 	 * entirely new peer for the new address. More addresses may be added
 	 * to this peer later, but not via this function. */
 	struct gtphub_peer *peer = gtphub_peer_new(hub, bind);
-	return gtphub_peer_add_addr(peer, addr);
+
+	a = gtphub_peer_add_addr(peer, addr);
+	
+	LOG("New peer address: %s\n",
+	    gsn_addr_to_str(&a->addr));
+
+	return a;
 }
 
 static struct gtphub_peer_port *gtphub_addr_add_port(struct gtphub_peer_addr *a,
@@ -1999,7 +2020,7 @@
 
 	llist_add(&pp->entry, &a->ports);
 
-	LOG("New peer: %s port %d\n",
+	LOG("New peer port: %s port %d\n",
 	    gsn_addr_to_str(&a->addr),
 	    (int)port);