gtphub: fix numerous segfaults, and other stupidities.

Initialize llist_heads to empty (2 were missing). Move those for struct gtphub
instances to gtphub_zero() (one moved, one added).

In from_[gs]gsns_read_cb(), use a return type that can actually reflect
negative return values.

resolved_addr.buf: no need to take the address of a byte array var
(cosmetic).

Pass the proper user data address to sgsn_ares_query(), not the address of
the pointer holding the user data address.

Initialize ggsn_lookup->expiry_entry (was missing). Publish the function for that
in gtphub.h so gtphub_ext.c can use it.

Sponsored-by: On-Waves ehi
diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h
index 79f138b..a012566 100644
--- a/openbsc/include/openbsc/gtphub.h
+++ b/openbsc/include/openbsc/gtphub.h
@@ -182,6 +182,9 @@
 /* Add a new mapping, or restart the expiry timeout for an already listed mapping. */
 void expiry_add(struct expiry *exq, struct expiring_item *mapping, time_t now);
 
+/* Initialize to all-empty; must be called before using the item in any way. */
+void expiring_item_init(struct expiring_item *item);
+
 /* Remove the given item from its expiry queue, and call item->del_cb, if set.
  * This sets item->del_cb to NULL and is harmless when run a second time on the
  * same item, so the del_cb may choose to call this function, too, to allow
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index b3638fe..f0c96bc 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -718,6 +718,8 @@
 static void gtphub_zero(struct gtphub *hub)
 {
 	ZERO_STRUCT(hub);
+	INIT_LLIST_HEAD(&hub->ggsn_lookups);
+	INIT_LLIST_HEAD(&hub->resolved_ggsns);
 }
 
 static int gtphub_sock_init(struct osmo_fd *ofd,
@@ -1243,7 +1245,7 @@
 	struct osmo_sockaddr from_addr;
 	struct osmo_sockaddr to_addr;
 	struct osmo_fd *to_ofd;
-	size_t len;
+	int len;
 	uint8_t *reply_buf;
 
 	len = gtphub_read(from_ggsns_ofd, &from_addr, buf, sizeof(buf));
@@ -1497,7 +1499,7 @@
 	struct osmo_sockaddr from_addr;
 	struct osmo_sockaddr to_addr;
 	struct osmo_fd *to_ofd;
-	size_t len;
+	int len;
 	uint8_t *reply_buf;
 
 	len = gtphub_read(from_sgsns_ofd, &from_addr, buf, sizeof(buf));
@@ -1796,8 +1798,6 @@
 {
 	gtphub_zero(hub);
 
-	INIT_LLIST_HEAD(&hub->resolved_ggsns);
-
 	expiry_init(&hub->expire_seq_maps, GTPH_SEQ_MAPPING_EXPIRY_SECS);
 	expiry_init(&hub->expire_tei_maps, GTPH_TEI_MAPPING_EXPIRY_MINUTES * 60);
 
diff --git a/openbsc/src/gprs/gtphub_ext.c b/openbsc/src/gprs/gtphub_ext.c
index 0d66273..98a9a40 100644
--- a/openbsc/src/gprs/gtphub_ext.c
+++ b/openbsc/src/gprs/gtphub_ext.c
@@ -94,7 +94,7 @@
 		goto remove_from_queue;
 	}
 
-	memcpy(&resolved_addr.buf, addr0, hostent->h_length);
+	memcpy(resolved_addr.buf, addr0, hostent->h_length);
 	resolved_addr.len = hostent->h_length;
 
 	LOGP(DGTPHUB, LOGL_NOTICE, "resolved addr %s\n",
@@ -122,7 +122,7 @@
 {
 	LOGP(DGTPHUB, LOGL_DEBUG, "Going to query %s (%p / %p)\n", lookup->apn_oi_str, lookup, &lookup->expiry_entry);
 
-	int rc = sgsn_ares_query(sgsn, lookup->apn_oi_str, ggsn_lookup_cb, &lookup);
+	int rc = sgsn_ares_query(sgsn, lookup->apn_oi_str, ggsn_lookup_cb, lookup);
 	if (rc != 0)
 		LOGP(DGTPHUB, LOGL_ERROR, "Failed to start ares query.\n");
 	return rc;
@@ -155,6 +155,7 @@
 	LOGP(DGTPHUB, LOGL_NOTICE, "Request to resolve IMSI '%s' with APN-NI '%s' (%p / %p)\n",
 	     imsi_str, apn_ni_str, lookup, &lookup->expiry_entry);
 
+	expiring_item_init(&lookup->expiry_entry);
 	lookup->hub = hub;
 
 	strncpy(lookup->imsi_str, imsi_str, sizeof(lookup->imsi_str));