/* GTP Hub Implementation */

/* (C) 2015 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * Author: Neels Hofmeyr
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <time.h>
#include <limits.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <gtp.h>
#include <gtpie.h>

#include <osmocom/sgsn/gtphub.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gprs_utils.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>

#include <osmocom/gsm/apn.h>


static const int GTPH_GC_TICK_SECONDS = 1;

void *osmo_gtphub_ctx;

/* Convenience makro, note: only within this C file. */
#define LOG(level, fmt, args...) \
	LOGP(DGTPHUB, level, fmt, ##args)

#define ZERO_STRUCT(struct_pointer) memset(struct_pointer, '\0', \
					   sizeof(*(struct_pointer)))

/* TODO move this to osmocom/core/select.h ? */
typedef int (*osmo_fd_cb_t)(struct osmo_fd *fd, unsigned int what);

/* TODO move this to osmocom/core/linuxlist.h ? */
#define __llist_first(head) (((head)->next == (head)) ? NULL : (head)->next)
#define llist_first(head, type, entry) \
	llist_entry(__llist_first(head), type, entry)

#define __llist_last(head) (((head)->next == (head)) ? NULL : (head)->prev)
#define llist_last(head, type, entry) \
	llist_entry(__llist_last(head), type, entry)

/* TODO move GTP header stuff to openggsn/gtp/ ? See gtp_decaps*() */

enum gtp_rc {
	GTP_RC_UNKNOWN = 0,
	GTP_RC_TINY = 1,    /* no IEs (like ping/pong) */
	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,
	GTP_RC_INVALID_IE = -3,
};

struct gtp_packet_desc {
	union gtp_packet *data;
	int data_len;
	int header_len;
	int version;
	uint8_t type;
	uint16_t seq;
	uint32_t header_tei_rx;
	uint32_t header_tei;
	int rc; /* enum gtp_rc */
	unsigned int plane_idx;
	unsigned int side_idx;
	struct gtphub_tunnel *tun;
	time_t timestamp;
	union gtpie_member *ie[GTPIE_SIZE];
};

struct pending_delete {
	struct llist_head entry;
	struct expiring_item expiry_entry;

	struct gtphub_tunnel *tun;
	uint8_t teardown_ind;
	uint8_t nsapi;
};


/* counters */

enum gtphub_counters_io {
	GTPH_CTR_PKTS_IN = 0,
	GTPH_CTR_PKTS_OUT,
	GTPH_CTR_BYTES_IN,
	GTPH_CTR_BYTES_OUT
};

static const struct rate_ctr_desc gtphub_counters_io_desc[] = {
	{ "packets.in",  "Packets ( In)" },
	{ "packets.out", "Packets (Out)" },
	{ "bytes.in",    "Bytes   ( In)" },
	{ "bytes.out",   "Bytes   (Out)" },
};

static const struct rate_ctr_group_desc gtphub_ctrg_io_desc = {
	.group_name_prefix = "gtphub:bind",
	.group_description = "I/O Statistics",
	.num_ctr = ARRAY_SIZE(gtphub_counters_io_desc),
	.ctr_desc = gtphub_counters_io_desc,
	.class_id = OSMO_STATS_CLASS_GLOBAL,
};


/* support */

static const char *gtp_type_str(uint8_t type)
{
	switch (type) {
	case 1:
		return " (Echo Request)";
	case 2:
		return " (Echo Response)";
	case 16:
		return " (Create PDP Ctx Request)";
	case 17:
		return " (Create PDP Ctx Response)";
	case 18:
		return " (Update PDP Ctx Request)";
	case 19:
		return " (Update PDP Ctx Response)";
	case 20:
		return " (Delete PDP Ctx Request)";
	case 21:
		return " (Delete PDP Ctx Response)";
	case 255:
		return " (User Data)";
	default:
		return "";
	}
}

void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src)
{
	*gsna = *src;
}

int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port,
			   const struct osmo_sockaddr *sa)
{
	char addr_str[256];
	char port_str[6];

	if (osmo_sockaddr_to_strs(addr_str, sizeof(addr_str),
				  port_str, sizeof(port_str),
				  sa, (NI_NUMERICHOST | NI_NUMERICSERV))
	    != 0) {
		return -1;
	}

	if (port)
		*port = atoi(port_str);

	return gsn_addr_from_str(gsna, addr_str);
}

int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str)
{
	if ((!gsna) || (!numeric_addr_str))
		return -1;

	int af = AF_INET;
	gsna->len = 4;
	const char *pos = numeric_addr_str;
	for (; *pos; pos++) {
		if (*pos == ':') {
			af = AF_INET6;
			gsna->len = 16;
			break;
		}
	}

	int rc = inet_pton(af, numeric_addr_str, gsna->buf);
	if (rc != 1) {
		LOG(LOGL_ERROR, "Cannot resolve numeric address: '%s'\n",
		    numeric_addr_str);
		return -1;
	}
	return 0;
}

const char *gsn_addr_to_str(const struct gsn_addr *gsna)
{
	static char buf[INET6_ADDRSTRLEN + 1];
	return gsn_addr_to_strb(gsna, buf, sizeof(buf));
}

const char *gsn_addr_to_strb(const struct gsn_addr *gsna,
			     char *strbuf,
			     int strbuf_len)
{
	int af;
	switch (gsna->len) {
	case 4:
		af = AF_INET;
		break;
	case 16:
		af = AF_INET6;
		break;
	default:
		return NULL;
	}

	const char *r = inet_ntop(af, gsna->buf, strbuf, strbuf_len);
	if (!r) {
		LOG(LOGL_ERROR, "Cannot convert gsn_addr to string:"
		    " %s: len=%d, buf=%s\n",
		    strerror(errno),
		    (int)gsna->len,
		    osmo_hexdump(gsna->buf, sizeof(gsna->buf)));
	}
	return r;
}

int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b)
{
	if (a == b)
		return 1;
	if ((!a) || (!b))
		return 0;
	if (a->len != b->len)
		return 0;
	return (memcmp(a->buf, b->buf, a->len) == 0)? 1 : 0;
}

static int gsn_addr_get(struct gsn_addr *gsna, const struct gtp_packet_desc *p,
			int idx)
{
	if (p->rc != GTP_RC_PDU_C)
		return -1;

	unsigned int len;
	/* gtpie.h fails to declare gtpie_gettlv()'s first arg as const. */
	if (gtpie_gettlv((union gtpie_member**)p->ie, GTPIE_GSN_ADDR, idx,
			 &len, gsna->buf, sizeof(gsna->buf))
	    != 0)
		return -1;
	gsna->len = len;
	return 0;
}

static int gsn_addr_put(const struct gsn_addr *gsna, struct gtp_packet_desc *p,
			int idx)
{
	if (p->rc != GTP_RC_PDU_C)
		return -1;

	int ie_idx;
	ie_idx = gtpie_getie(p->ie, GTPIE_GSN_ADDR, idx);

	if (ie_idx < 0)
		return -1;

	struct gtpie_tlv *ie = &p->ie[ie_idx]->tlv;
	int ie_l = ntoh16(ie->l);
	if (ie_l != gsna->len) {
		LOG(LOGL_ERROR, "Not implemented:"
		    " replace an IE address of different size:"
		    " replace %d with %d\n", (int)ie_l, (int)gsna->len);
		return -1;
	}

	memcpy(ie->v, gsna->buf, (int)ie_l);
	return 0;
}

/* Validate GTP version 0 data; analogous to validate_gtp1_header(), see there.
 */
void validate_gtp0_header(struct gtp_packet_desc *p)
{
	const struct gtp0_header *pheader = &(p->data->gtp0.h);
	p->rc = GTP_RC_UNKNOWN;
	p->header_len = 0;

	OSMO_ASSERT(p->data_len >= 1);
	OSMO_ASSERT(p->version == 0);

	if (p->data_len < GTP0_HEADER_SIZE) {
		LOG(LOGL_ERROR, "GTP0 packet too short: %d\n", p->data_len);
		p->rc = GTP_RC_TOOSHORT;
		return;
	}

	p->type = ntoh8(pheader->type);
	p->seq = ntoh16(pheader->seq);
	p->header_tei_rx = 0; /* TODO */
	p->header_tei = p->header_tei_rx;

	if (p->data_len == GTP0_HEADER_SIZE) {
		p->rc = GTP_RC_TINY;
		p->header_len = GTP0_HEADER_SIZE;
		return;
	}

	/* Check packet length field versus length of packet */
	if (p->data_len != (ntoh16(pheader->length) + GTP0_HEADER_SIZE)) {
		LOG(LOGL_ERROR, "GTP packet length field (%d + %d) does not"
		    " match actual length (%d)\n",
		    GTP0_HEADER_SIZE, (int)ntoh16(pheader->length),
		    p->data_len);
		p->rc = GTP_RC_TOOSHORT;
		return;
	}

	LOG(LOGL_DEBUG, "GTP v0 TID = %" PRIu64 "\n", pheader->tid);
	p->header_len = GTP0_HEADER_SIZE;
	p->rc = GTP_RC_PDU_C;
}

/* Validate GTP version 1 data, and update p->rc with the result, as well as
 * p->header_len in case of a valid header. */
void validate_gtp1_header(struct gtp_packet_desc *p)
{
	const struct gtp1_header_long *pheader = &(p->data->gtp1l.h);
	p->rc = GTP_RC_UNKNOWN;
	p->header_len = 0;

	OSMO_ASSERT(p->data_len >= 1);
	OSMO_ASSERT(p->version == 1);

	if ((p->data_len < GTP1_HEADER_SIZE_LONG)
	    && (p->data_len != GTP1_HEADER_SIZE_SHORT)){
		LOG(LOGL_ERROR, "GTP packet too short: %d\n", p->data_len);
		p->rc = GTP_RC_TOOSHORT;
		return;
	}

	p->type = ntoh8(pheader->type);
	p->header_tei_rx = ntoh32(pheader->tei);
	p->header_tei = p->header_tei_rx;
	p->seq = ntoh16(pheader->seq);

	LOG(LOGL_DEBUG, "| GTPv1\n");
	LOG(LOGL_DEBUG, "| type = %" PRIu8 " 0x%02" PRIx8 "\n", p->type, p->type);
	LOG(LOGL_DEBUG, "| length = %" PRIu16 " 0x%04" PRIx16 "\n", ntoh16(pheader->length), ntoh16(pheader->length));
	LOG(LOGL_DEBUG, "| TEI = %" PRIu32 " 0x%08" PRIx32 "\n", p->header_tei_rx, p->header_tei_rx);
	LOG(LOGL_DEBUG, "| seq = %" PRIu16 " 0x%04" PRIx16 "\n", p->seq, p->seq);
	LOG(LOGL_DEBUG, "| npdu = %" PRIu8 " 0x%02" PRIx8 "\n", pheader->npdu, pheader->npdu);
	LOG(LOGL_DEBUG, "| next = %" PRIu8 " 0x%02" PRIx8 "\n", pheader->next, pheader->next);

	if (p->data_len <= GTP1_HEADER_SIZE_LONG) {
		p->rc = GTP_RC_TINY;
		p->header_len = GTP1_HEADER_SIZE_SHORT;
		return;
	}

	/* Check packet length field versus length of packet */
	int announced_len = ntoh16(pheader->length) + GTP1_HEADER_SIZE_SHORT;
	if (p->data_len != announced_len) {
		LOG(LOGL_ERROR, "GTP packet length field (%d + %d) does not"
		    " match actual length (%d)\n",
		    GTP1_HEADER_SIZE_SHORT, (int)ntoh16(pheader->length),
		    p->data_len);
		p->rc = GTP_RC_TOOSHORT;
		return;
	}

	p->rc = GTP_RC_PDU_C;
	p->header_len = GTP1_HEADER_SIZE_LONG;
}

/* Examine whether p->data of size p->data_len has a valid GTP header. Set
 * p->version, p->rc and p->header_len. On error, p->rc <= 0 (see enum
 * gtp_rc). p->data must point at a buffer with p->data_len set. */
void validate_gtp_header(struct gtp_packet_desc *p)
{
	p->rc = GTP_RC_UNKNOWN;

	/* Need at least 1 byte in order to check version */
	if (p->data_len < 1) {
		LOG(LOGL_ERROR, "Discarding packet - too small: %d\n",
		    p->data_len);
		p->rc = GTP_RC_TOOSHORT;
		return;
	}

	p->version = p->data->flags >> 5;

	switch (p->version) {
	case 0:
		validate_gtp0_header(p);
		break;
	case 1:
		validate_gtp1_header(p);
		break;
	default:
		LOG(LOGL_ERROR, "Unsupported GTP version: %d\n", p->version);
		p->rc = GTP_RC_UNSUPPORTED_VERSION;
		break;
	}
}


/* Return the value of the i'th IMSI IEI by copying to *imsi.
 * The first IEI is reached by passing i = 0.
 * imsi must point at allocated space of (at least) 8 bytes.
 * Return 1 on success, or 0 if not found. */
static int get_ie_imsi(union gtpie_member *ie[], int i, uint8_t *imsi)
{
	return gtpie_gettv0(ie, GTPIE_IMSI, i, imsi, 8) == 0;
}

/* Analogous to get_ie_imsi(). nsapi must point at a single uint8_t. */
static int get_ie_nsapi(union gtpie_member *ie[], int i, uint8_t *nsapi)
{
	return gtpie_gettv1(ie, GTPIE_NSAPI, i, nsapi) == 0;
}

static char imsi_digit_to_char(uint8_t nibble)
{
	nibble &= 0x0f;
	if (nibble > 9)
		return (nibble == 0x0f) ? '\0' : '?';
	return '0' + nibble;
}

/* Return a human readable IMSI string, in a static buffer.
 * imsi must point at 8 octets of IMSI IE encoded IMSI data. */
static int imsi_to_str(uint8_t *imsi, const char **imsi_str)
{
	static char str[17];
	int i;

	for (i = 0; i < 8; i++) {
		char c;
		c = imsi_digit_to_char(imsi[i]);
		if (c == '?')
			return -1;
		str[2*i] = c;

		c = imsi_digit_to_char(imsi[i] >> 4);
		if (c == '?')
			return -1;
		str[2*i + 1] = c;
	}
	str[16] = '\0';
	*imsi_str = str;
	return 1;
}

/* Return 0 if not present, 1 if present and decoded successfully, -1 if
 * present but cannot be decoded. */
static int get_ie_imsi_str(union gtpie_member *ie[], int i,
			   const char **imsi_str)
{
	uint8_t imsi_buf[8];
	if (!get_ie_imsi(ie, i, imsi_buf))
		return 0;
	return imsi_to_str(imsi_buf, imsi_str);
}

/* Return 0 if not present, 1 if present and decoded successfully, -1 if
 * present but cannot be decoded. */
static int get_ie_apn_str(union gtpie_member *ie[], const char **apn_str)
{
	static char apn_buf[GSM_APN_LENGTH];
	unsigned int len;
	if (gtpie_gettlv(ie, GTPIE_APN, 0,
			 &len, apn_buf, sizeof(apn_buf)) != 0)
		return 0;

	if (len < 2) {
		LOG(LOGL_ERROR, "APN IE: invalid length: %d\n",
		    (int)len);
		return -1;
	}

	if (len > (sizeof(apn_buf) - 1))
		len = sizeof(apn_buf) - 1;
	apn_buf[len] = '\0';

	*apn_str = osmo_apn_to_str(apn_buf, (uint8_t*)apn_buf, len);
	if (!(*apn_str)) {
		LOG(LOGL_ERROR, "APN IE: present but cannot be decoded: %s\n",
		    osmo_hexdump((uint8_t*)apn_buf, len));
		return -1;
	}
	return 1;
}


/* Validate header, and index information elements. Write decoded packet
 * information to *res. res->data will point at the given data buffer. On
 * error, p->rc is set <= 0 (see enum gtp_rc). */
static void gtp_decode(const uint8_t *data, int data_len,
		       unsigned int from_side_idx,
		       unsigned int from_plane_idx,
		       struct gtp_packet_desc *res,
		       time_t now)
{
	ZERO_STRUCT(res);
	res->data = (union gtp_packet*)data;
	res->data_len = data_len;
	res->side_idx = from_side_idx;
	res->plane_idx = from_plane_idx;
	res->timestamp = now;

	validate_gtp_header(res);

	if (res->rc <= 0)
		return;

	LOG(LOGL_DEBUG, "Valid GTP header (v%d)\n", res->version);

	if (from_plane_idx == GTPH_PLANE_USER) {
		res->rc = GTP_RC_PDU_U;
		return;
	}

	if (res->rc != GTP_RC_PDU_C) {
		LOG(LOGL_DEBUG, "no IEs in this GTP packet\n");
		return;
	}

	if (gtpie_decaps(res->ie, res->version,
			 (void*)(data + res->header_len),
			 res->data_len - res->header_len) != 0) {
		res->rc = GTP_RC_INVALID_IE;
		LOG(LOGL_ERROR, "INVALID: cannot decode IEs."
		    " Dropping GTP packet%s.\n",
		    gtp_type_str(res->type)
		    );
		return;
	}

#if 1
	/* TODO if (<loglevel is debug>)
	   (waiting for a commit from jerlbeck) */
	int i;

	for (i = 0; i < 10; i++) {
		const char *imsi;
		if (get_ie_imsi_str(res->ie, i, &imsi) < 1)
			break;
		LOG(LOGL_DEBUG, "| IMSI %s\n", imsi);
	}

	for (i = 0; i < 10; i++) {
		uint8_t nsapi;
		if (!get_ie_nsapi(res->ie, i, &nsapi))
			break;
		LOG(LOGL_DEBUG, "| NSAPI %d\n", (int)nsapi);
	}

	for (i = 0; i < 2; i++) {
		struct gsn_addr addr;
		if (gsn_addr_get(&addr, res, i) == 0)
			LOG(LOGL_DEBUG, "| addr %s\n", gsn_addr_to_str(&addr));
	}

	for (i = 0; i < 10; i++) {
		uint32_t tei;
		if (gtpie_gettv4(res->ie, GTPIE_TEI_DI, i, &tei) != 0)
			break;
		LOG(LOGL_DEBUG, "| TEI DI (USER) %" PRIu32 " 0x%08" PRIx32 "\n",
		    tei, tei);
	}

	for (i = 0; i < 10; i++) {
		uint32_t tei;
		if (gtpie_gettv4(res->ie, GTPIE_TEI_C, i, &tei) != 0)
			break;
		LOG(LOGL_DEBUG, "| TEI (CTRL) %" PRIu32 " 0x%08" PRIx32 "\n",
		    tei, tei);
	}
#endif
}


/* expiry */

void expiry_init(struct expiry *exq, int expiry_in_seconds)
{
	ZERO_STRUCT(exq);
	exq->expiry_in_seconds = expiry_in_seconds;
	INIT_LLIST_HEAD(&exq->items);
}

void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now)
{
	item->expiry = now + exq->expiry_in_seconds;

	OSMO_ASSERT(llist_empty(&exq->items)
		    || (item->expiry
			>= llist_last(&exq->items, struct expiring_item, entry)->expiry));

	/* Add/move to the tail to always sort by expiry, ascending. */
	llist_del(&item->entry);
	llist_add_tail(&item->entry, &exq->items);
}

int expiry_tick(struct expiry *exq, time_t now)
{
	int expired = 0;
	struct expiring_item *m, *n;
	llist_for_each_entry_safe(m, n, &exq->items, entry) {
		if (m->expiry <= now) {
			expiring_item_del(m);
			expired ++;
		} else {
			/* The items are added sorted by expiry. So when we hit
			 * an unexpired entry, only more unexpired ones will
			 * follow. */
			break;
		}
	}
	return expired;
}

void expiry_clear(struct expiry *exq)
{
	struct expiring_item *m, *n;
	llist_for_each_entry_safe(m, n, &exq->items, entry) {
		expiring_item_del(m);
	}
}

void expiring_item_init(struct expiring_item *item)
{
	ZERO_STRUCT(item);
	INIT_LLIST_HEAD(&item->entry);
}

void expiring_item_del(struct expiring_item *item)
{
	OSMO_ASSERT(item);
	llist_del(&item->entry);
	INIT_LLIST_HEAD(&item->entry);
	if (item->del_cb) {
		/* avoid loops */
		del_cb_t del_cb = item->del_cb;
		item->del_cb = 0;
		(del_cb)(item);
	}
}


/* nr_map, nr_pool */

void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max)
{
	*pool = (struct nr_pool){
		.nr_min = nr_min,
		.nr_max = nr_max,
		.last_nr = nr_max
	};
}

nr_t nr_pool_next(struct nr_pool *pool)
{
	if (pool->last_nr >= pool->nr_max)
		pool->last_nr = pool->nr_min;
	else
		pool->last_nr ++;

	return pool->last_nr;
}

void nr_map_init(struct nr_map *map, struct nr_pool *pool,
		 struct expiry *exq)
{
	ZERO_STRUCT(map);
	map->pool = pool;
	map->add_items_to_expiry = exq;
	INIT_LLIST_HEAD(&map->mappings);
}

void nr_mapping_init(struct nr_mapping *m)
{
	ZERO_STRUCT(m);
	INIT_LLIST_HEAD(&m->entry);
	expiring_item_init(&m->expiry_entry);
}

void nr_map_add(struct nr_map *map, struct nr_mapping *mapping, time_t now)
{
	/* Generate a mapped number */
	mapping->repl = nr_pool_next(map->pool);

	/* Add to the tail to always yield a list sorted by expiry, in
	 * ascending order. */
	llist_add_tail(&mapping->entry, &map->mappings);
	nr_map_refresh(map, mapping, now);
}

void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping, time_t now)
{
	if (!map->add_items_to_expiry)
		return;
	expiry_add(map->add_items_to_expiry,
		   &mapping->expiry_entry,
		   now);
}

void nr_map_clear(struct nr_map *map)
{
	struct nr_mapping *m;
	struct nr_mapping *n;
	llist_for_each_entry_safe(m, n, &map->mappings, entry) {
		nr_mapping_del(m);
	}
}

int nr_map_empty(const struct nr_map *map)
{
	return llist_empty(&map->mappings);
}

struct nr_mapping *nr_map_get(const struct nr_map *map,
			      void *origin, nr_t nr_orig)
{
	struct nr_mapping *mapping;
	llist_for_each_entry(mapping, &map->mappings, entry) {
		if ((mapping->origin == origin)
		    && (mapping->orig == nr_orig))
			return mapping;
	}
	/* Not found. */
	return NULL;
}

struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl)
{
	struct nr_mapping *mapping;
	llist_for_each_entry(mapping, &map->mappings, entry) {
		if (mapping->repl == nr_repl) {
			return mapping;
		}
	}
	/* Not found. */
	return NULL;
}

void nr_mapping_del(struct nr_mapping *mapping)
{
	OSMO_ASSERT(mapping);
	llist_del(&mapping->entry);
	INIT_LLIST_HEAD(&mapping->entry);
	expiring_item_del(&mapping->expiry_entry);
}


/* gtphub */

const char* const gtphub_plane_idx_names[GTPH_PLANE_N] = {
	"CTRL",
	"USER",
};

const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N] = {
	2123,
	2152,
};

const char* const gtphub_side_idx_names[GTPH_SIDE_N] = {
	"SGSN",
	"GGSN",
};

time_t gtphub_now(void)
{
	struct timespec now_tp;
	OSMO_ASSERT(clock_gettime(CLOCK_MONOTONIC, &now_tp) >= 0);
	return now_tp.tv_sec;
}

/* Remove a gtphub_peer from its list and free it. */
static void gtphub_peer_del(struct gtphub_peer *peer)
{
	OSMO_ASSERT(llist_empty(&peer->addresses));
	nr_map_clear(&peer->seq_map);
	llist_del(&peer->entry);
	talloc_free(peer);
}

static void gtphub_peer_addr_del(struct gtphub_peer_addr *pa)
{
	OSMO_ASSERT(llist_empty(&pa->ports));
	llist_del(&pa->entry);
	talloc_free(pa);
}

static void gtphub_peer_port_del(struct gtphub_peer_port *pp)
{
	OSMO_ASSERT(pp->ref_count == 0);
	llist_del(&pp->entry);
	rate_ctr_group_free(pp->counters_io);
	talloc_free(pp);
}

/* From the information in the gtp_packet_desc, return the address of a GGSN.
 * Return -1 on error. */
static int gtphub_resolve_ggsn(struct gtphub *hub,
			       struct gtp_packet_desc *p,
			       struct gtphub_peer_port **pp);

/* See gtphub_ext.c (wrapped by unit test) */
struct gtphub_peer_port *gtphub_resolve_ggsn_addr(struct gtphub *hub,
						  const char *imsi_str,
						  const char *apn_ni_str);
int gtphub_ares_init(struct gtphub *hub);

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,
			    const struct gtphub_cfg_addr *addr,
			    osmo_fd_cb_t cb,
			    void *data,
			    int ofd_id)
{
	if (!addr->addr_str) {
		LOG(LOGL_FATAL, "Cannot bind: empty address.\n");
		return -1;
	}
	if (!addr->port) {
		LOG(LOGL_FATAL, "Cannot bind: zero port not permitted.\n");
		return -1;
	}

	ofd->when = BSC_FD_READ;
	ofd->cb = cb;
	ofd->data = data;
	ofd->priv_nr = ofd_id;

	int rc;
	rc = osmo_sock_init_ofd(ofd,
				AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
				addr->addr_str, addr->port,
				OSMO_SOCK_F_BIND);
	if (rc < 1) {
		LOG(LOGL_FATAL, "Cannot bind to %s port %d (rc %d)\n",
		    addr->addr_str, (int)addr->port, rc);
		return -1;
	}

	return 0;
}

static void gtphub_sock_close(struct osmo_fd *ofd)
{
	close(ofd->fd);
	osmo_fd_unregister(ofd);
	ofd->cb = NULL;
}

static void gtphub_bind_init(struct gtphub_bind *b, uint32_t idx)
{
	ZERO_STRUCT(b);

	INIT_LLIST_HEAD(&b->peers);

	b->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
					      &gtphub_ctrg_io_desc, idx);
	OSMO_ASSERT(b->counters_io);
}

static int gtphub_bind_start(struct gtphub_bind *b,
			     const struct gtphub_cfg_bind *cfg,
			     osmo_fd_cb_t cb, void *cb_data,
			     unsigned int ofd_id)
{
	LOG(LOGL_DEBUG, "Starting bind %s\n", b->label);
	if (gsn_addr_from_str(&b->local_addr, cfg->bind.addr_str) != 0) {
		LOG(LOGL_FATAL, "Invalid bind address for %s: %s\n",
		    b->label, cfg->bind.addr_str);
		return -1;
	}
	if (gtphub_sock_init(&b->ofd, &cfg->bind, cb, cb_data, ofd_id) != 0) {
		LOG(LOGL_FATAL, "Cannot bind for %s: %s\n",
		    b->label, cfg->bind.addr_str);
		return -1;
	}
	b->local_port = cfg->bind.port;
	return 0;
}

static void gtphub_bind_free(struct gtphub_bind *b)
{
	OSMO_ASSERT(llist_empty(&b->peers));
	if (b->counters_io)
		rate_ctr_group_free(b->counters_io);
}

static void gtphub_bind_stop(struct gtphub_bind *b) {
	gtphub_sock_close(&b->ofd);
	gtphub_bind_free(b);
}

/* Recv datagram from from->fd, write sender's address to *from_addr.
 * Return the number of bytes read, zero on error. */
static int gtphub_read(const struct osmo_fd *from,
		       struct osmo_sockaddr *from_addr,
		       uint8_t *buf, size_t buf_len)
{
	OSMO_ASSERT(from_addr);

	/* recvfrom requires the available length set in *from_addr_len. */
	from_addr->l = sizeof(from_addr->a);
	errno = 0;
	ssize_t received = recvfrom(from->fd, buf, buf_len, 0,
				    (struct sockaddr*)&from_addr->a,
				    &from_addr->l);
	/* TODO use recvmsg and get a MSG_TRUNC flag to make sure the message
	 * is not truncated. Then maybe reduce buf's size. */

	if (received <= 0) {
		LOG((errno == EAGAIN? LOGL_DEBUG : LOGL_ERROR),
		    "error: %s\n", strerror(errno));
		return 0;
	}

	LOG(LOGL_DEBUG, "Received %d bytes from %s: %s%s\n",
	    (int)received, osmo_sockaddr_to_str(from_addr),
	    osmo_hexdump(buf, received > 1000? 1000 : received),
	    received > 1000 ? "..." : "");

	return received;
}

static inline void gtphub_port_ref_count_inc(struct gtphub_peer_port *pp)
{
	OSMO_ASSERT(pp);
	OSMO_ASSERT(pp->ref_count < UINT_MAX);
	pp->ref_count++;
}

static inline void gtphub_port_ref_count_dec(struct gtphub_peer_port *pp)
{
	OSMO_ASSERT(pp);
	OSMO_ASSERT(pp->ref_count > 0);
	pp->ref_count--;
}

static inline void set_seq(struct gtp_packet_desc *p, uint16_t seq)
{
	OSMO_ASSERT(p->version == 1);
	p->data->gtp1l.h.seq = hton16(seq);
	p->seq = seq;
}

static inline void set_tei(struct gtp_packet_desc *p, uint32_t tei)
{
	OSMO_ASSERT(p->version == 1);
	p->data->gtp1l.h.tei = hton32(tei);
	p->header_tei = tei;
}

static void gtphub_mapping_del_cb(struct expiring_item *expi);

static struct nr_mapping *gtphub_mapping_new()
{
	struct nr_mapping *nrm;
	nrm = talloc_zero(osmo_gtphub_ctx, struct nr_mapping);
	OSMO_ASSERT(nrm);

	nr_mapping_init(nrm);
	nrm->expiry_entry.del_cb = gtphub_mapping_del_cb;
	return nrm;
}


#define APPEND(args...) \
		l = snprintf(pos, left, args); \
		pos += l; \
		left -= l

static const char *gtphub_tunnel_side_str(struct gtphub_tunnel *tun,
					  int side_idx)
{
	static char buf[256];
	char *pos = buf;
	int left = sizeof(buf);
	int l;
	                 
	struct gtphub_tunnel_endpoint *c, *u;
	c = &tun->endpoint[side_idx][GTPH_PLANE_CTRL];
	u = &tun->endpoint[side_idx][GTPH_PLANE_USER];

	/* print both only if they differ. */
	if (!c->peer) {
		APPEND("(uninitialized)");
	} else {
		APPEND("%s", gsn_addr_to_str(&c->peer->peer_addr->addr));
	}

	if (!u->peer) {
		if (c->peer) {
			APPEND("/(uninitialized)");
		}
	} else if ((!c->peer)
		   || (!gsn_addr_same(&u->peer->peer_addr->addr,
				      &c->peer->peer_addr->addr))) {
		APPEND("/%s", gsn_addr_to_str(&u->peer->peer_addr->addr));
	}

	APPEND(" (TEI C=%x U=%x)",
	       c->tei_orig,
	       u->tei_orig);
	return buf;
}

const char *gtphub_tunnel_str(struct gtphub_tunnel *tun)
{
	static char buf[512];
	char *pos = buf;
	int left = sizeof(buf);
	int l;

	if (!tun)
		return "null-tunnel";

	APPEND("TEI=%x: ", tun->tei_repl);
	APPEND("%s", gtphub_tunnel_side_str(tun, GTPH_SIDE_SGSN));
	APPEND(" <-> %s", gtphub_tunnel_side_str(tun, GTPH_SIDE_GGSN));

	return buf;
}

#undef APPEND

void gtphub_tunnel_endpoint_set_peer(struct gtphub_tunnel_endpoint *te,
				     struct gtphub_peer_port *pp)
{
	if (te->peer)
		gtphub_port_ref_count_dec(te->peer);
	te->peer = pp;
	if (te->peer)
		gtphub_port_ref_count_inc(te->peer);
}

int gtphub_tunnel_complete(struct gtphub_tunnel *tun)
{
	if (!tun)
		return 0;
	if (!tun->tei_repl)
		return 0;
	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		struct gtphub_tunnel_endpoint *te =
			&tun->endpoint[side_idx][plane_idx];
		if (!(te->peer && te->tei_orig))
			return 0;
	}
	return 1;
}

static void gtphub_tunnel_del_cb(struct expiring_item *expi)
{
	struct gtphub_tunnel *tun = container_of(expi,
						 struct gtphub_tunnel,
						 expiry_entry);
	LOG(LOGL_DEBUG, "expired: %s\n", gtphub_tunnel_str(tun));

	llist_del(&tun->entry);
	INIT_LLIST_HEAD(&tun->entry); /* mark unused */

	expi->del_cb = 0; /* avoid recursion loops */
	expiring_item_del(&tun->expiry_entry); /* usually already done, but make sure. */

	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];

		/* clear ref count */
		gtphub_tunnel_endpoint_set_peer(te, NULL);

		rate_ctr_group_free(te->counters_io);
	}

	talloc_free(tun);
}

#define CTR_IDX(s, p, a, b) (a + s + (p + b) * 2)

/* rate counter index for tunnels: [3; 6] */
#define CTR_IDX_TUN(s, p) CTR_IDX(s, p, 1, 1)

/* rate counter index for hubs: [7; 10] */
#define CTR_IDX_HUB(s, p) CTR_IDX(s, p, 3, 2)

static struct gtphub_tunnel *gtphub_tunnel_new()
{
	struct gtphub_tunnel *tun;
	tun = talloc_zero(osmo_gtphub_ctx, struct gtphub_tunnel);
	OSMO_ASSERT(tun);

	INIT_LLIST_HEAD(&tun->entry);
	expiring_item_init(&tun->expiry_entry);

	int side_idx, plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][plane_idx];
		te->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
						       &gtphub_ctrg_io_desc,
						       CTR_IDX_TUN(side_idx, plane_idx));
		if (!te->counters_io)
			return NULL;
	}

	tun->expiry_entry.del_cb = gtphub_tunnel_del_cb;
	return tun;
}

static const char *gtphub_peer_strb(struct gtphub_peer *peer, char *buf,
				    int buflen)
{
	if (llist_empty(&peer->addresses))
		return "(addressless)";

	struct gtphub_peer_addr *a = llist_first(&peer->addresses,
						 struct gtphub_peer_addr,
						 entry);
	return gsn_addr_to_strb(&a->addr, buf, buflen);
}

static const char *gtphub_port_strb(struct gtphub_peer_port *port, char *buf,
				    int buflen)
{
	if (!port)
		return "(null port)";

	snprintf(buf, buflen, "%s port %d",
		 gsn_addr_to_str(&port->peer_addr->addr),
		 (int)port->port);
	return buf;
}

const char *gtphub_peer_str(struct gtphub_peer *peer)
{
	static char buf[256];
	return gtphub_peer_strb(peer, buf, sizeof(buf));
}

const char *gtphub_port_str(struct gtphub_peer_port *port)
{
	static char buf[256];
	return gtphub_port_strb(port, buf, sizeof(buf));
}

static const char *gtphub_port_str2(struct gtphub_peer_port *port)
{
	static char buf[256];
	return gtphub_port_strb(port, buf, sizeof(buf));
}

static void gtphub_mapping_del_cb(struct expiring_item *expi)
{
	expi->del_cb = 0; /* avoid recursion loops */
	expiring_item_del(expi); /* usually already done, but make sure. */

	struct nr_mapping *nrm = container_of(expi,
					      struct nr_mapping,
					      expiry_entry);
	llist_del(&nrm->entry);
	INIT_LLIST_HEAD(&nrm->entry); /* mark unused */

	/* Just for log */
	struct gtphub_peer_port *from = nrm->origin;
	OSMO_ASSERT(from);
	LOG(LOGL_DEBUG, "expired: %d: nr mapping from %s: %u->%u\n",
	    (int)nrm->expiry_entry.expiry,
	    gtphub_port_str(from),
	    (unsigned int)nrm->orig, (unsigned int)nrm->repl);

	gtphub_port_ref_count_dec(from);

	talloc_free(nrm);
}

static struct nr_mapping *gtphub_mapping_have(struct nr_map *map,
					      struct gtphub_peer_port *from,
					      nr_t orig_nr,
					      time_t now)
{
	struct nr_mapping *nrm;

	nrm = nr_map_get(map, from, orig_nr);

	if (!nrm) {
		nrm = gtphub_mapping_new();
		nrm->orig = orig_nr;
		nrm->origin = from;
		nr_map_add(map, nrm, now);
		gtphub_port_ref_count_inc(from);
		LOG(LOGL_DEBUG, "peer %s: sequence map %d --> %d\n",
		    gtphub_port_str(from),
		    (int)(nrm->orig), (int)(nrm->repl));
	} else {
		nr_map_refresh(map, nrm, now);
	}

	OSMO_ASSERT(nrm);
	return nrm;
}

static void gtphub_map_seq(struct gtp_packet_desc *p,
			   struct gtphub_peer_port *from_port,
			   struct gtphub_peer_port *to_port)
{
	/* Store a mapping in to_peer's map, so when we later receive a GTP
	 * packet back from to_peer, the seq nr can be unmapped back to its
	 * origin (from_peer here). */
	struct nr_mapping *nrm;
	nrm = gtphub_mapping_have(&to_port->peer_addr->peer->seq_map,
				  from_port, p->seq, p->timestamp);

	/* Change the GTP packet to yield the new, mapped seq nr */
	set_seq(p, nrm->repl);
}

static struct gtphub_peer_port *gtphub_unmap_seq(struct gtp_packet_desc *p,
						 struct gtphub_peer_port *responding_port)
{
	OSMO_ASSERT(p->version == 1);
	struct nr_mapping *nrm =
		nr_map_get_inv(&responding_port->peer_addr->peer->seq_map,
			       p->seq);
	if (!nrm)
		return NULL;
	LOG(LOGL_DEBUG, "peer %p: sequence unmap %d <-- %d\n",
	    nrm->origin, (int)(nrm->orig), (int)(nrm->repl));
	set_seq(p, nrm->orig);
	return nrm->origin;
}

static int gtphub_check_mapped_tei(struct gtphub_tunnel *new_tun,
				   struct gtphub_tunnel *iterated_tun,
				   uint32_t *tei_min,
				   uint32_t *tei_max)
{
	if (!new_tun->tei_repl || !iterated_tun->tei_repl)
		return 1;

	*tei_min = (*tei_min < iterated_tun->tei_repl)? *tei_min : iterated_tun->tei_repl;
	*tei_max = (*tei_max > iterated_tun->tei_repl)? *tei_max : iterated_tun->tei_repl;

	if (new_tun->tei_repl != iterated_tun->tei_repl)
		return 1;

	/* new_tun->tei_repl is already taken. Try to find one out of the known
	 * range. */
	LOG(LOGL_DEBUG, "TEI replacement %d already taken.\n", new_tun->tei_repl);

	if ((*tei_max) < 0xffffffff) {
		(*tei_max)++;
		new_tun->tei_repl = *tei_max;
		LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl);
		return 1;
	} else if ((*tei_min) > 1) {
		(*tei_min)--;
		new_tun->tei_repl = *tei_min;
		LOG(LOGL_DEBUG, "Using TEI %d instead.\n", new_tun->tei_repl);
		return 1;
	}

	/* None seems to be available. */
	return 0;
}

static int gtphub_check_reused_teis(struct gtphub *hub,
				    struct gtphub_tunnel *new_tun)
{
	uint32_t tei_min = 0xffffffff;
	uint32_t tei_max = 0;
	int side_idx;
	int plane_idx;
	struct gtphub_tunnel_endpoint *te;
	struct gtphub_tunnel_endpoint *te2;

	struct gtphub_tunnel *tun, *ntun;

	llist_for_each_entry_safe(tun, ntun, &hub->tunnels, entry) {
		if (tun == new_tun)
			continue;

		/* Check whether the GSN sent a TEI that it is reusing from a
		 * previous tunnel. */
		int tun_continue = 0;
		for_each_side(side_idx) {
			for_each_plane(plane_idx) {
				te = &tun->endpoint[side_idx][plane_idx];
				te2 = &new_tun->endpoint[side_idx][plane_idx];
				if ((te->tei_orig == 0)
				    || (te->tei_orig != te2->tei_orig)
				    || (!te->peer)
				    || (!te2->peer)
				    || !gsn_addr_same(&te->peer->peer_addr->addr,
						      &te2->peer->peer_addr->addr))
					continue;

				/* The peer is reusing a TEI that I believe to
				 * be part of another tunnel. The other tunnel
				 * must be stale, then. */
				LOG(LOGL_NOTICE,
				    "Expiring tunnel due to reused TEI:"
				    " %s peer %s sent %s TEI %x,"
				    " previously used by tunnel %s...\n",
				    gtphub_side_idx_names[side_idx],
				    gtphub_port_str(te->peer),
				    gtphub_plane_idx_names[plane_idx],
				    te->tei_orig,
				    gtphub_tunnel_str(tun));
				LOG(LOGL_NOTICE, "...while establishing tunnel %s\n",
				    gtphub_tunnel_str(new_tun));

				expiring_item_del(&tun->expiry_entry);
				/* continue to find more matches. There shouldn't be
				 * any, but let's make sure. However, tun is deleted,
				 * so we need to skip to the next tunnel. */
				tun_continue = 1;
				break;
			}
			if (tun_continue)
				break;
		}
		if (tun_continue)
			continue;

		/* Check whether the mapped TEI is already used by another
		 * tunnel. */
		if (!gtphub_check_mapped_tei(new_tun, tun, &tei_min, &tei_max)) {
			LOG(LOGL_ERROR,
			    "No mapped TEI is readily available."
			    " Searching for holes between occupied"
			    " TEIs not implemented.");
			return 0;
		}

	}

	return 1;
}

static void gtphub_tunnel_refresh(struct gtphub *hub,
				  struct gtphub_tunnel *tun,
				  time_t now)
{
	expiry_add(&hub->expire_slowly,
		   &tun->expiry_entry,
		   now);
}

static struct gtphub_tunnel_endpoint *gtphub_unmap_tei(struct gtphub *hub,
						       struct gtp_packet_desc *p,
						       struct gtphub_peer_port *from,
						       struct gtphub_tunnel **unmapped_from_tun)
{
	OSMO_ASSERT(from);
	int other_side = other_side_idx(p->side_idx);

	struct gtphub_tunnel *tun;
	llist_for_each_entry(tun, &hub->tunnels, entry) {
		struct gtphub_tunnel_endpoint *te_from =
			&tun->endpoint[p->side_idx][p->plane_idx];
		struct gtphub_tunnel_endpoint *te_to =
			&tun->endpoint[other_side][p->plane_idx];
		if ((tun->tei_repl == p->header_tei_rx)
		    && te_from->peer
		    && gsn_addr_same(&te_from->peer->peer_addr->addr,
				     &from->peer_addr->addr)) {
			gtphub_tunnel_refresh(hub, tun, p->timestamp);
			if (unmapped_from_tun)
				*unmapped_from_tun = tun;
			return te_to;
		}
	}

	if (unmapped_from_tun)
		*unmapped_from_tun = NULL;
	return NULL;
}

static void gtphub_map_restart_counter(struct gtphub *hub,
				       struct gtp_packet_desc *p)
{
	if (p->rc != GTP_RC_PDU_C)
		return;

	int ie_idx;
	ie_idx = gtpie_getie(p->ie, GTPIE_RECOVERY, 0);
	if (ie_idx < 0)
		return;

	/* Always send gtphub's own restart counter */
	p->ie[ie_idx]->tv1.v = hton8(hub->restart_counter);
}

static int gtphub_unmap_header_tei(struct gtphub_peer_port **to_port_p,
				   struct gtphub_tunnel **unmapped_from_tun,
				   struct gtphub *hub,
				   struct gtp_packet_desc *p,
				   struct gtphub_peer_port *from_port)
{
	OSMO_ASSERT(p->version == 1);
	*to_port_p = NULL;
	if (unmapped_from_tun)
		*unmapped_from_tun = NULL;

	/* If the header's TEI is zero, no PDP context has been established
	 * yet. If nonzero, a mapping should actually already exist for this
	 * TEI, since it must have been announced in a PDP context creation. */
	if (!p->header_tei_rx)
		return 0;

	/* to_peer has previously announced a TEI, which was stored and
	 * mapped in a tunnel struct. */
	struct gtphub_tunnel_endpoint *to;
	to = gtphub_unmap_tei(hub, p, from_port, unmapped_from_tun);
	if (!to) {
		LOG(LOGL_ERROR, "Received unknown TEI %" PRIx32 " from %s\n",
		    p->header_tei_rx, gtphub_port_str(from_port));
		return -1;
	}

	if (unmapped_from_tun) {
		OSMO_ASSERT(*unmapped_from_tun);
		LOG(LOGL_DEBUG, "Unmapped TEI coming from: %s\n",
		    gtphub_tunnel_str(*unmapped_from_tun));
	}

	uint32_t unmapped_tei = to->tei_orig;
	set_tei(p, unmapped_tei);

	/* May be NULL for an invalidated tunnel. */
	*to_port_p = to->peer;

	return 0;
}

static int gtphub_handle_create_pdp_ctx(struct gtphub *hub,
					struct gtp_packet_desc *p,
					struct gtphub_peer_port *from_ctrl,
					struct gtphub_peer_port *to_ctrl)
{
	int plane_idx;

	osmo_static_assert((GTPH_PLANE_CTRL == 0) && (GTPH_PLANE_USER == 1),
			   plane_nrs_match_GSN_addr_IE_indices);

	struct gtphub_tunnel *tun = p->tun;

	if (p->type == GTP_CREATE_PDP_REQ) {
		if (p->side_idx != GTPH_SIDE_SGSN) {
			LOG(LOGL_ERROR, "Wrong side: Create PDP Context"
			    " Request from the GGSN side: %s",
			    gtphub_port_str(from_ctrl));
			return -1;
		}

		if (tun) {
			LOG(LOGL_ERROR, "Not implemented: Received"
			    " Create PDP Context Request for an already"
			    " established tunnel:"
			    " from %s, tunnel %s\n",
			    gtphub_port_str(from_ctrl),
			    gtphub_tunnel_str(p->tun));
			return -1;
		}

		/* A new tunnel. */
		tun = gtphub_tunnel_new();
		if (!tun) {
			LOG(LOGL_ERROR, "Failed to allocate new tunnel %s <-> %s\n",
			    gtphub_port_str(from_ctrl), gtphub_port_str(to_ctrl));
			return -1;
		}
		p->tun = tun;

		/* Create TEI mapping */
		tun->tei_repl = nr_pool_next(&hub->tei_pool);

		llist_add(&tun->entry, &hub->tunnels);
		gtphub_tunnel_refresh(hub, tun, p->timestamp);
		/* The endpoint peers on this side (SGSN) will be set from IEs
		 * below. Also set the GGSN Ctrl endpoint, for logging. */
		gtphub_tunnel_endpoint_set_peer(&tun->endpoint[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL],
						to_ctrl);
	} else if (p->type == GTP_CREATE_PDP_RSP) {
		if (p->side_idx != GTPH_SIDE_GGSN) {
			LOG(LOGL_ERROR, "Wrong side: Create PDP Context"
			    " Response from the SGSN side: %s",
			    gtphub_port_str(from_ctrl));
			return -1;
		}

		/* The tunnel should already have been resolved from the header
		 * TEI and be available in tun (== p->tun). Just fill in the
		 * GSN Addresses below.*/
		OSMO_ASSERT(tun);
		OSMO_ASSERT(tun->tei_repl == p->header_tei_rx);
		OSMO_ASSERT(to_ctrl);
	}

	uint8_t ie_type[] = { GTPIE_TEI_C, GTPIE_TEI_DI };
	int ie_mandatory = (p->type == GTP_CREATE_PDP_REQ);
	unsigned int side_idx = p->side_idx;

	for_each_plane(plane_idx) {
		int rc;
		struct gsn_addr use_addr;
		uint16_t use_port;
		uint32_t tei_from_ie;
		int ie_idx;

		/* Fetch GSN Address and TEI from IEs. As ensured by above
		 * static asserts, plane_idx corresponds to the GSN Address IE
		 * index (the first one = 0 = ctrl, second one = 1 = user). */
		rc = gsn_addr_get(&use_addr, p, plane_idx);
		if (rc) {
			LOG(LOGL_ERROR, "Cannot read %s GSN Address IE\n",
			    gtphub_plane_idx_names[plane_idx]);
			return -1;
		}
		LOG(LOGL_DEBUG, "Read %s GSN addr %s (%d)\n",
		    gtphub_plane_idx_names[plane_idx],
		    gsn_addr_to_str(&use_addr),
		    use_addr.len);

		ie_idx = gtpie_getie(p->ie, ie_type[plane_idx], 0);
		if (ie_idx < 0) {
			if (ie_mandatory) {
				LOG(LOGL_ERROR,
				    "Create PDP Context message invalid:"
				    " missing IE %d\n",
				    (int)ie_type[plane_idx]);
				return -1;
			}
			tei_from_ie = 0;
		}
		else
			tei_from_ie = ntoh32(p->ie[ie_idx]->tv4.v);

		/* Make sure an entry for this peer address with default port
		 * exists.
		 *
		 * Exception: if sgsn_use_sender is set, instead use the
		 * sender's address and port for Ctrl -- the User port is not
		 * known until the first User packet arrives.
		 *
		 * Note: doing this here is just an optimization, because
		 * gtphub_handle_buf() has code to replace the tunnel
		 * endpoints' addresses with the sender (needed for User
		 * plane). We could just ignore sgsn_use_sender here. But if we
		 * set up a default port here and replace it in
		 * gtphub_handle_buf(), we'd be creating a peer port just to
		 * expire it right away. */
		if (hub->sgsn_use_sender && (side_idx == GTPH_SIDE_SGSN)) {
			int rc = gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa);
			if (rc < 0)
				LOG(LOGL_ERROR, "%s(): failed to obtain GSN address\n", __func__);
		} else {
			use_port = gtphub_plane_idx_default_port[plane_idx];

		}

		struct gtphub_peer_port *peer_from_ie;
		peer_from_ie = gtphub_port_have(hub,
						&hub->to_gsns[side_idx][plane_idx],
						&use_addr, use_port);

		gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][plane_idx],
						peer_from_ie);

		if (!tei_from_ie &&
		    !tun->endpoint[side_idx][plane_idx].tei_orig) {
			LOG(LOGL_ERROR,
			    "Create PDP Context message omits %s TEI, but"
			    " no TEI has been announced for this tunnel: %s\n",
			    gtphub_plane_idx_names[plane_idx],
			    gtphub_tunnel_str(tun));
			return -1;
		}

		if (tei_from_ie) {
			/* Replace TEI in GTP packet IE */
			tun->endpoint[side_idx][plane_idx].tei_orig = tei_from_ie;
			p->ie[ie_idx]->tv4.v = hton32(tun->tei_repl);

			if (!gtphub_check_reused_teis(hub, tun)) {
				/* It's highly unlikely that all TEIs are
				 * taken. But the code looking for an unused
				 * TEI is, at the time of writing this comment,
				 * not able to find gaps in the TEI space. To
				 * explicitly alert the user of this problem,
				 * rather abort than carry on. */
				LOG(LOGL_FATAL, "TEI range exhausted. Cannot create TEI mapping, aborting.\n");
				abort();
			}
		}

		/* Replace the GSN address to reflect gtphub. */
		rc = gsn_addr_put(&hub->to_gsns[other_side_idx(side_idx)][plane_idx].local_addr,
				  p, plane_idx);
		if (rc) {
			LOG(LOGL_ERROR, "Cannot write %s GSN Address IE\n",
			    gtphub_plane_idx_names[plane_idx]);
			return -1;
		}
	}

	if (p->type == GTP_CREATE_PDP_REQ) {
		LOG(LOGL_DEBUG, "New tunnel, first half: %s\n",
		    gtphub_tunnel_str(tun));
	} else if (p->type == GTP_CREATE_PDP_RSP) {
		LOG(LOGL_DEBUG, "New tunnel: %s\n",
		    gtphub_tunnel_str(tun));
	}

	return 0;
}

static void pending_delete_del_cb(struct expiring_item *expi)
{
	struct pending_delete *pd;
	pd = container_of(expi, struct pending_delete, expiry_entry);

	llist_del(&pd->entry);
	INIT_LLIST_HEAD(&pd->entry);

	pd->expiry_entry.del_cb = 0;
	expiring_item_del(&pd->expiry_entry);

	talloc_free(pd);
}

static struct pending_delete *pending_delete_new(void)
{
	struct pending_delete *pd = talloc_zero(osmo_gtphub_ctx, struct pending_delete);
	INIT_LLIST_HEAD(&pd->entry);
	expiring_item_init(&pd->expiry_entry);
	pd->expiry_entry.del_cb = pending_delete_del_cb;
	return pd;
}

static int gtphub_handle_delete_pdp_ctx(struct gtphub *hub,
					struct gtp_packet_desc *p,
					struct gtphub_peer_port *from_ctrl,
					struct gtphub_peer_port *to_ctrl)
{
	struct gtphub_tunnel *known_tun = p->tun;

	if (p->type == GTP_DELETE_PDP_REQ) {
		if (!known_tun) {
			LOG(LOGL_ERROR, "Cannot find tunnel for Delete PDP Context Request.\n");
			return -1;
		}

		/* Store the Delete Request until a successful Response is seen. */
		uint8_t teardown_ind;
		uint8_t nsapi;

		if (gtpie_gettv1(p->ie, GTPIE_TEARDOWN, 0, &teardown_ind) != 0) {
			LOG(LOGL_ERROR, "Missing Teardown Ind IE in Delete PDP Context Request.\n");
			return -1;
		}

		if (gtpie_gettv1(p->ie, GTPIE_NSAPI, 0, &nsapi) != 0) {
			LOG(LOGL_ERROR, "Missing NSAPI IE in Delete PDP Context Request.\n");
			return -1;
		}

		struct pending_delete *pd = NULL;

		struct pending_delete *pdi = NULL;
		llist_for_each_entry(pdi, &hub->pending_deletes, entry) {
			if ((pdi->tun == known_tun)
			    && (pdi->teardown_ind == teardown_ind)
			    && (pdi->nsapi == nsapi)) {
				pd = pdi;
				break;
			}
		}

		if (!pd) {
			pd = pending_delete_new();
			pd->tun = known_tun;
			pd->teardown_ind = teardown_ind;
			pd->nsapi = nsapi;

			LOG(LOGL_DEBUG, "Tunnel delete pending: %s\n",
			    gtphub_tunnel_str(known_tun));
			llist_add(&pd->entry, &hub->pending_deletes);
		}

		/* Add or refresh timeout. */
		expiry_add(&hub->expire_quickly, &pd->expiry_entry, p->timestamp);

		/* If a pending_delete should expire before the response to
		 * indicate success comes in, the responding peer will have the
		 * tunnel deactivated, while the requesting peer gets no reply
		 * and keeps the tunnel. The hope is that the requesting peer
		 * will try again and get a useful response. */
	} else if (p->type == GTP_DELETE_PDP_RSP) {
		/* Find the Delete Request for this Response. */
		struct pending_delete *pd = NULL;

		struct pending_delete *pdi;
		llist_for_each_entry(pdi, &hub->pending_deletes, entry) {
			if (known_tun == pdi->tun) {
				pd = pdi;
				break;
			}
		}

		if (!pd) {
			LOG(LOGL_ERROR, "Delete PDP Context Response:"
			    " Cannot find matching request.");
			/* If we delete the tunnel now, anyone can send a
			 * Delete response to kill tunnels at will. */
			return -1;
		}

		/* TODO handle teardown_ind and nsapi */

		expiring_item_del(&pd->expiry_entry);

		uint8_t cause;
		if (gtpie_gettv1(p->ie, GTPIE_CAUSE, 0, &cause) != 0) {
			LOG(LOGL_ERROR, "Delete PDP Context Response:"
			    " Missing Cause IE.");
			/* If we delete the tunnel now, at least one of the
			 * peers may still think it is active. */
			return -1;
		}

		if (cause != GTPCAUSE_ACC_REQ) {
			LOG(LOGL_NOTICE,
			    "Delete PDP Context Response indicates failure;"
			    "for %s\n",
			    gtphub_tunnel_str(known_tun));
			return -1;
		}

		LOG(LOGL_DEBUG, "Delete PDP Context: removing tunnel %s\n",
		    gtphub_tunnel_str(known_tun));
		p->tun = NULL;
		expiring_item_del(&known_tun->expiry_entry);
	}

	return 0;
}

static int gtphub_handle_update_pdp_ctx(struct gtphub *hub,
					struct gtp_packet_desc *p,
					struct gtphub_peer_port *from_ctrl,
					struct gtphub_peer_port *to_ctrl)
{
	/* TODO */
	return 0;
}

/* Read GSN address IEs from p, and make sure these peer addresses exist in
 * bind[plane_idx] with default ports, in their respective planes (both Ctrl
 * and User). Map TEIs announced in IEs, and write mapped TEIs in-place into
 * the packet p. */
static int gtphub_handle_pdp_ctx(struct gtphub *hub,
				 struct gtp_packet_desc *p,
				 struct gtphub_peer_port *from_ctrl,
				 struct gtphub_peer_port *to_ctrl)
{
	OSMO_ASSERT(p->plane_idx == GTPH_PLANE_CTRL);

	switch (p->type) {
	case GTP_CREATE_PDP_REQ:
	case GTP_CREATE_PDP_RSP:
		return gtphub_handle_create_pdp_ctx(hub, p,
						    from_ctrl, to_ctrl);

	case GTP_DELETE_PDP_REQ:
	case GTP_DELETE_PDP_RSP:
		return gtphub_handle_delete_pdp_ctx(hub, p,
						    from_ctrl, to_ctrl);

	case GTP_UPDATE_PDP_REQ:
	case GTP_UPDATE_PDP_RSP:
		return gtphub_handle_update_pdp_ctx(hub, p,
						    from_ctrl, to_ctrl);

	default:
		/* Nothing to do for this message type. */
		return 0;
	}

}

static int gtphub_send_del_pdp_ctx(struct gtphub *hub,
				   struct gtphub_tunnel *tun,
				   int to_side)
{
	static uint8_t del_ctx_msg[16] = {
		0x32,	/* GTP v1 flags */
		GTP_DELETE_PDP_REQ,
		0x00, 0x08, /* Length in network byte order */
		0x00, 0x00, 0x00, 0x00,	/* TEI to be replaced */
		0, 0,	/* Seq, to be replaced */
		0, 0,	/* no extensions */
		0x13, 0xff,  /* 19: Teardown ind = 1 */
		0x14, 0	/* 20: NSAPI = 0 */
	};

	uint32_t *tei = (uint32_t*)&del_ctx_msg[4];
	uint16_t *seq = (uint16_t*)&del_ctx_msg[8];

	struct gtphub_tunnel_endpoint *te =
		&tun->endpoint[to_side][GTPH_PLANE_CTRL];

	if (! te->peer)
		return 0;

	*tei = hton32(te->tei_orig);
	*seq = hton16(nr_pool_next(&te->peer->peer_addr->peer->seq_pool));

	struct gtphub_bind *to_bind = &hub->to_gsns[to_side][GTPH_PLANE_CTRL];
	int rc = gtphub_write(&to_bind->ofd, &te->peer->sa,
			      del_ctx_msg, sizeof(del_ctx_msg));
	if (rc != 0) {
		LOG(LOGL_ERROR,
		    "Failed to send out-of-band Delete PDP Context Request to %s\n",
		    gtphub_port_str(te->peer));
	}
	return rc;
}

/* Tell all peers on the other end of tunnels that PDP contexts are void. */
static void gtphub_restarted(struct gtphub *hub,
			     struct gtp_packet_desc *p,
			     struct gtphub_peer_port *pp)
{
	LOG(LOGL_NOTICE, "Peer has restarted: %s\n",
	    gtphub_port_str(pp));

	int deleted_count = 0;
	struct gtphub_tunnel *tun;
	llist_for_each_entry(tun, &hub->tunnels, entry) {
		int side_idx;
		for_each_side(side_idx) {
			struct gtphub_tunnel_endpoint *te = &tun->endpoint[side_idx][GTPH_PLANE_CTRL];
			struct gtphub_tunnel_endpoint *te2 = &tun->endpoint[other_side_idx(side_idx)][GTPH_PLANE_CTRL];
			if ((!te->peer)
			    || (!te2->tei_orig)
			    || (pp->peer_addr->peer != te->peer->peer_addr->peer))
				continue;

			LOG(LOGL_DEBUG, "Deleting tunnel due to peer restart: %s\n",
			    gtphub_tunnel_str(tun));
			deleted_count ++;

			/* Send a Delete PDP Context Request to the
			 * peer on the other side, remember the pending
			 * delete and wait for the response to delete
			 * the tunnel. Clear this side of the tunnel to
			 * make sure it isn't used.
			 *
			 * Should the delete message send fail, or if no
			 * response is received, this tunnel will expire. If
			 * its TEIs come up in a new PDP Context Request, it
			 * will be removed. If messages for this tunnel should
			 * come in (from the not restarted side), they will be
			 * dropped because the tunnel is rendered unusable. */
			gtphub_send_del_pdp_ctx(hub, tun, other_side_idx(side_idx));

			gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_CTRL],
							NULL);
			gtphub_tunnel_endpoint_set_peer(&tun->endpoint[side_idx][GTPH_PLANE_USER],
							NULL);
		}
	}

	if (deleted_count)
		LOG(LOGL_NOTICE, "Deleting %d tunnels due to restart of: %s\n",
		    deleted_count,
		    gtphub_port_str(pp));
}

static int get_restart_count(struct gtp_packet_desc *p)
{
	int ie_idx;
	ie_idx = gtpie_getie(p->ie, GTPIE_RECOVERY, 0);
	if (ie_idx < 0)
		return -1;
	return ntoh8(p->ie[ie_idx]->tv1.v);
}

static void gtphub_check_restart_counter(struct gtphub *hub,
					 struct gtp_packet_desc *p,
					 struct gtphub_peer_port *from)
{
	/* If the peer is sending a Recovery IE (7.7.11) with a restart counter
	 * that doesn't match the peer's previously sent restart counter, clear
	 * that peer and cancel PDP contexts. */

	int restart = get_restart_count(p);

	if ((restart < 0) || (restart > 255))
		return;

	if ((from->last_restart_count >= 0) && (from->last_restart_count <= 255)) {
		if (from->last_restart_count != restart) {
			gtphub_restarted(hub, p, from);
		}
	}

	from->last_restart_count = restart;
}

static int from_sgsns_read_cb(struct osmo_fd *from_sgsns_ofd, unsigned int what)
{
	unsigned int plane_idx = from_sgsns_ofd->priv_nr;
	OSMO_ASSERT(plane_idx < GTPH_PLANE_N);
	LOG(LOGL_DEBUG, "=== reading from SGSN (%s)\n",
	    gtphub_plane_idx_names[plane_idx]);

	if (!(what & BSC_FD_READ))
		return 0;

	struct gtphub *hub = from_sgsns_ofd->data;

	static uint8_t buf[4096];
	struct osmo_sockaddr from_addr;
	struct osmo_sockaddr to_addr;
	struct osmo_fd *to_ofd;
	int len;
	uint8_t *reply_buf;

	len = gtphub_read(from_sgsns_ofd, &from_addr, buf, sizeof(buf));
	if (len < 1)
		return 0;

	len = gtphub_handle_buf(hub, GTPH_SIDE_SGSN, plane_idx, &from_addr,
				buf, len, gtphub_now(),
				&reply_buf, &to_ofd, &to_addr);
	if (len < 1)
		return 0;

	return gtphub_write(to_ofd, &to_addr, reply_buf, len);
}

static int from_ggsns_read_cb(struct osmo_fd *from_ggsns_ofd, unsigned int what)
{
	unsigned int plane_idx = from_ggsns_ofd->priv_nr;
	OSMO_ASSERT(plane_idx < GTPH_PLANE_N);
	LOG(LOGL_DEBUG, "=== reading from GGSN (%s)\n",
	    gtphub_plane_idx_names[plane_idx]);
	if (!(what & BSC_FD_READ))
		return 0;

	struct gtphub *hub = from_ggsns_ofd->data;

	static uint8_t buf[4096];
	struct osmo_sockaddr from_addr;
	struct osmo_sockaddr to_addr;
	struct osmo_fd *to_ofd;
	int len;
	uint8_t *reply_buf;

	len = gtphub_read(from_ggsns_ofd, &from_addr, buf, sizeof(buf));
	if (len < 1)
		return 0;

	len = gtphub_handle_buf(hub, GTPH_SIDE_GGSN, plane_idx, &from_addr,
				buf, len, gtphub_now(),
				&reply_buf, &to_ofd, &to_addr);
	if (len < 1)
		return 0;

	return gtphub_write(to_ofd, &to_addr, reply_buf, len);
}

static int gtphub_unmap(struct gtphub *hub,
			struct gtp_packet_desc *p,
			struct gtphub_peer_port *from,
			struct gtphub_peer_port *to_proxy,
			struct gtphub_peer_port **final_unmapped,
			struct gtphub_peer_port **unmapped_from_seq)
{
	/* Always (try to) unmap sequence and TEI numbers, which need to be
	 * replaced in the packet. Either way, give precedence to the proxy, if
	 * configured. */

	if (unmapped_from_seq)
		*unmapped_from_seq = NULL;
	if (final_unmapped)
		*final_unmapped = NULL;
	p->tun = NULL;

	struct gtphub_peer_port *from_seq = NULL;
	struct gtphub_peer_port *from_tei = NULL;
	struct gtphub_peer_port *unmapped = NULL;

	from_seq = gtphub_unmap_seq(p, from);

	if (gtphub_unmap_header_tei(&from_tei, &p->tun, hub, p, from) < 0)
		return -1;

	struct gtphub_peer *from_peer = from->peer_addr->peer;
	if (from_seq && from_tei && (from_seq != from_tei)) {
		LOG(LOGL_DEBUG,
		    "Seq unmap and TEI unmap yield two different peers."
		    " Using seq unmap."
		    " (from %s %s: seq %d yields %s, tei %u yields %s)\n",
		    gtphub_plane_idx_names[p->plane_idx],
		    gtphub_peer_str(from_peer),
		    (int)p->seq,
		    gtphub_port_str(from_seq),
		    (unsigned int)p->header_tei_rx,
		    gtphub_port_str2(from_tei)
		   );
	}
	unmapped = (from_seq? from_seq : from_tei);

	if (unmapped && to_proxy && (unmapped != to_proxy)) {
		LOG(LOGL_NOTICE,
		    "Unmap yields a different peer than the configured proxy."
		    " Using proxy."
		    " unmapped: %s  proxy: %s\n",
		    gtphub_port_str(unmapped),
		    gtphub_port_str2(to_proxy)
		   );
	}
	unmapped = (to_proxy? to_proxy : unmapped);

	if (!unmapped) {
		/* Return no error, but returned pointers are all NULL. */
		return 0;
	}

	if (unmapped_from_seq)
		*unmapped_from_seq = from_seq;
	if (final_unmapped)
		*final_unmapped = unmapped;
	return 0;
}

static int gsn_addr_to_sockaddr(struct gsn_addr *src,
				uint16_t port,
				struct osmo_sockaddr *dst)
{
	return osmo_sockaddr_init_udp(dst, gsn_addr_to_str(src), port);
}

/* If p is an Echo request, replace p's data with the matching response and
 * return 1. If p is no Echo request, return 0, or -1 if an invalid packet is
 * detected. */
static int gtphub_handle_echo_req(struct gtphub *hub, struct gtp_packet_desc *p,
				  uint8_t **reply_buf)
{
	if (p->type != GTP_ECHO_REQ)
		return 0;

	static uint8_t echo_response_data[14] = {
		0x32,	/* GTP v1 flags */
		GTP_ECHO_RSP,
		0x00, 14 - 8, /* Length in network byte order */
		0x00, 0x00, 0x00, 0x00,	/* Zero TEI */
		0, 0,	/* Seq, to be replaced */
		0, 0,	/* no extensions */
		0x0e,	/* Recovery IE */
		0	/* Restart counter, to be replaced */
	};
	uint16_t *seq = (uint16_t*)&echo_response_data[8];
	uint8_t *recovery = &echo_response_data[13];

	*seq = hton16(p->seq);
	*recovery = hub->restart_counter;

	*reply_buf = echo_response_data;

	return sizeof(echo_response_data);
}

struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind,
						     const struct osmo_sockaddr *addr);

/* Parse buffer as GTP packet, replace elements in-place and return the ofd and
 * address to forward to. Return a pointer to the osmo_fd, but copy the
 * sockaddr to *to_addr. The reason for this is that the sockaddr may expire at
 * any moment, while the osmo_fd is guaranteed to persist. Return the number of
 * bytes to forward, 0 or less on failure. */
int gtphub_handle_buf(struct gtphub *hub,
		      unsigned int side_idx,
		      unsigned int plane_idx,
		      const struct osmo_sockaddr *from_addr,
		      uint8_t *buf,
		      size_t received,
		      time_t now,
		      uint8_t **reply_buf,
		      struct osmo_fd **to_ofd,
		      struct osmo_sockaddr *to_addr)
{
	struct gtphub_bind *from_bind = &hub->to_gsns[side_idx][plane_idx];
	struct gtphub_bind *to_bind = &hub->to_gsns[other_side_idx(side_idx)][plane_idx];

	rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_IN],
		     received);

	struct gtp_packet_desc p;
	gtp_decode(buf, received, side_idx, plane_idx, &p, now);

	LOG(LOGL_DEBUG, "%s rx %s from %s %s%s\n",
	    (side_idx == GTPH_SIDE_GGSN)? "<-" : "->",
	    gtphub_plane_idx_names[plane_idx],
	    gtphub_side_idx_names[side_idx],
	    osmo_sockaddr_to_str(from_addr),
	    gtp_type_str(p.type));

	if (p.rc <= 0) {
		LOG(LOGL_ERROR, "INVALID: dropping GTP packet%s from %s %s %s\n",
		    gtp_type_str(p.type),
		    gtphub_side_idx_names[side_idx],
		    gtphub_plane_idx_names[plane_idx],
		    osmo_sockaddr_to_str(from_addr));
		return -1;
	}

	rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_IN]);

	int reply_len;
	reply_len = gtphub_handle_echo_req(hub, &p, reply_buf);
	if (reply_len > 0) {
		/* It was an echo. Nothing left to do. */
		osmo_sockaddr_copy(to_addr, from_addr);
		*to_ofd = &from_bind->ofd;

		rate_ctr_inc(&from_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
		rate_ctr_add(&from_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT],
			     reply_len);
		LOG(LOGL_DEBUG, "%s Echo response to %s: %d bytes to %s\n",
		    (side_idx == GTPH_SIDE_GGSN)? "-->" : "<--",
		    gtphub_side_idx_names[side_idx],
		    (int)reply_len, osmo_sockaddr_to_str(to_addr));
		return reply_len;
	}
	if (reply_len < 0)
		return -1;

	*to_ofd = &to_bind->ofd;

	/* If a proxy is configured, check that it's indeed that proxy talking
	 * to us. A proxy is a forced 1:1 connection, e.g. to another gtphub,
	 * so no-one else is allowed to talk to us from that side. */
	struct gtphub_peer_port *from_peer = hub->proxy[side_idx][plane_idx];
	if (from_peer) {
		if (osmo_sockaddr_cmp(&from_peer->sa, from_addr) != 0) {
			LOG(LOGL_ERROR,
			    "Rejecting: %s proxy configured, but GTP packet"
			    " received on %s bind is from another sender:"
			    " proxy: %s  sender: %s\n",
			    gtphub_side_idx_names[side_idx],
			    gtphub_side_idx_names[side_idx],
			    gtphub_port_str(from_peer),
			    osmo_sockaddr_to_str(from_addr));
			return -1;
		}
	}

	if (!from_peer) {
		/* Find or create a peer with a matching address. The sender's
		 * port may in fact differ. */
		from_peer = gtphub_known_addr_have_port(from_bind, from_addr);
	}

	/* If any PDP context has been created, we already have an entry for
	 * this GSN. If we don't have an entry, a GGSN has nothing to tell us
	 * about, while an SGSN may initiate a PDP context. */
	if (!from_peer) {
		if (side_idx == GTPH_SIDE_GGSN) {
			LOG(LOGL_ERROR, "Dropping packet%s: unknown GGSN peer: %s\n",
			    gtp_type_str(p.type),
			    osmo_sockaddr_to_str(from_addr));
			return -1;
		} else {
			/* SGSN */
			/* A new peer. If this is on the Ctrl plane, an SGSN
			 * may make first contact without being known yet, so
			 * create the peer struct for the current sender. */
			if (plane_idx != GTPH_PLANE_CTRL) {
				LOG(LOGL_ERROR,
				    "Dropping packet%s: User plane peer was not"
				    "announced by PDP Context: %s\n",
				    gtp_type_str(p.type),
				    osmo_sockaddr_to_str(from_addr));
				return -1;
			}

			struct gsn_addr from_gsna;
			uint16_t from_port;
			if (gsn_addr_from_sockaddr(&from_gsna, &from_port, from_addr) != 0)
				return -1;

			from_peer = gtphub_port_have(hub, from_bind, &from_gsna, from_port);
		}
	}

	if (!from_peer) {
		/* This could theoretically happen for invalid address data or
		 * somesuch. */
		LOG(LOGL_ERROR, "Dropping packet%s: invalid %s peer: %s\n",
		    gtp_type_str(p.type),
		    gtphub_side_idx_names[side_idx],
		    osmo_sockaddr_to_str(from_addr));
		return -1;
	}

	rate_ctr_add(&from_peer->counters_io->ctr[GTPH_CTR_BYTES_IN],
		     received);
	rate_ctr_inc(&from_peer->counters_io->ctr[GTPH_CTR_PKTS_IN]);

	LOG(LOGL_DEBUG, "from %s peer: %s\n", gtphub_side_idx_names[side_idx],
	    gtphub_port_str(from_peer));

	gtphub_check_restart_counter(hub, &p, from_peer);
	gtphub_map_restart_counter(hub, &p);

	struct gtphub_peer_port *to_peer_from_seq;
	struct gtphub_peer_port *to_peer;
	if (gtphub_unmap(hub, &p, from_peer,
			 hub->proxy[other_side_idx(side_idx)][plane_idx],
			 &to_peer, &to_peer_from_seq)
	    != 0) {
		return -1;
	}

	if (p.tun) {
		struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[p.side_idx][p.plane_idx];
		rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_IN],
			     received);
		rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_IN]);
	}

	if ((!to_peer) && (side_idx == GTPH_SIDE_SGSN)) {
		if (gtphub_resolve_ggsn(hub, &p, &to_peer) < 0)
			return -1;
	}

	if (!to_peer && p.tun && p.type == GTP_DELETE_PDP_RSP) {
		/* It's a delete confirmation for a tunnel that is partly
		 * invalid, probably marked unsuable due to a restarted peer.
		 * Remove the tunnel and be happy without forwarding. */
		expiring_item_del(&p.tun->expiry_entry);
		p.tun = NULL;
		return 0;
	}

	if (!to_peer) {
		LOG(LOGL_ERROR, "No %s to send to. Dropping packet%s"
		    " (type=%" PRIu8 ", header-TEI=%" PRIx32 ", seq=%" PRIx16 ").\n",
		    gtphub_side_idx_names[other_side_idx(side_idx)],
		    gtp_type_str(p.type),
		    p.type, p.header_tei_rx, p.seq
		    );
		return -1;
	}

	if (plane_idx == GTPH_PLANE_CTRL) {
		/* This may be a Create PDP Context response. If it is, there
		 * are other addresses in the GTP message to set up apart from
		 * the sender. */
		if (gtphub_handle_pdp_ctx(hub, &p, from_peer, to_peer)
		    != 0)
			return -1;
	}
	
	/* Either to_peer was resolved from an existing tunnel,
	 * or a PDP Ctx and thus a tunnel has just been created,
	 * or the tunnel has been deleted due to this message. */
	OSMO_ASSERT(p.tun || (p.type == GTP_DELETE_PDP_RSP));

	/* If the GGSN is replying to an SGSN request, the sequence nr has
	 * already been unmapped above (to_peer_from_seq != NULL), and we need not
	 * create a new mapping. */
	if (!to_peer_from_seq)
		gtphub_map_seq(&p, from_peer, to_peer);

	osmo_sockaddr_copy(to_addr, &to_peer->sa);

	*reply_buf = (uint8_t*)p.data;

	if (received) {
		rate_ctr_inc(&to_bind->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
		rate_ctr_add(&to_bind->counters_io->ctr[GTPH_CTR_BYTES_OUT],
			     received);

		rate_ctr_inc(&to_peer->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
		rate_ctr_add(&to_peer->counters_io->ctr[GTPH_CTR_BYTES_OUT],
			     received);
	}

	if (p.tun) {
		struct gtphub_tunnel_endpoint *te = &p.tun->endpoint[other_side_idx(p.side_idx)][p.plane_idx];
		rate_ctr_inc(&te->counters_io->ctr[GTPH_CTR_PKTS_OUT]);
		rate_ctr_add(&te->counters_io->ctr[GTPH_CTR_BYTES_OUT],
			     received);
	}

	LOG(LOGL_DEBUG, "%s Forward to %s:"
	    " header-TEI %" PRIx32", seq %" PRIx16", %d bytes to %s\n",
	    (side_idx == GTPH_SIDE_SGSN)? "-->" : "<--",
	    gtphub_side_idx_names[other_side_idx(side_idx)],
	    p.header_tei, p.seq,
	    (int)received, osmo_sockaddr_to_str(to_addr));
	return received;
}

static void resolved_gssn_del_cb(struct expiring_item *expi)
{
	struct gtphub_resolved_ggsn *ggsn;
	ggsn = container_of(expi, struct gtphub_resolved_ggsn, expiry_entry);

	gtphub_port_ref_count_dec(ggsn->peer);
	llist_del(&ggsn->entry);

	ggsn->expiry_entry.del_cb = 0;
	expiring_item_del(&ggsn->expiry_entry);

	talloc_free(ggsn);
}

void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str,
			  struct gsn_addr *resolved_addr,
			  time_t now)
{
	struct gtphub_peer_port *pp;
	struct gtphub_resolved_ggsn *ggsn;

	LOG(LOGL_DEBUG, "Resolved GGSN callback: %s %s\n",
	    apn_oi_str, osmo_hexdump((unsigned char*)resolved_addr,
				     sizeof(*resolved_addr)));

	pp = gtphub_port_have(hub, &hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL],
			      resolved_addr, 2123);
	if (!pp) {
		LOG(LOGL_ERROR, "Internal: Cannot create/find peer '%s'\n",
		    gsn_addr_to_str(resolved_addr));
		return;
	}

	ggsn = talloc_zero(osmo_gtphub_ctx, struct gtphub_resolved_ggsn);
	OSMO_ASSERT(ggsn);
	INIT_LLIST_HEAD(&ggsn->entry);
	expiring_item_init(&ggsn->expiry_entry);

	ggsn->peer = pp;
	gtphub_port_ref_count_inc(pp);

	osmo_strlcpy(ggsn->apn_oi_str, apn_oi_str, sizeof(ggsn->apn_oi_str));

	ggsn->expiry_entry.del_cb = resolved_gssn_del_cb;
	expiry_add(&hub->expire_slowly, &ggsn->expiry_entry, now);

	llist_add(&ggsn->entry, &hub->resolved_ggsns);
}

static int gtphub_gc_peer_port(struct gtphub_peer_port *pp)
{
	return pp->ref_count == 0;
}

static int gtphub_gc_peer_addr(struct gtphub_peer_addr *pa)
{
	struct gtphub_peer_port *pp, *npp;
	llist_for_each_entry_safe(pp, npp, &pa->ports, entry) {
		if (gtphub_gc_peer_port(pp)) {
			LOG(LOGL_DEBUG, "expired: peer %s\n",
			    gtphub_port_str(pp));
			gtphub_peer_port_del(pp);
		}
	}
	return llist_empty(&pa->ports);
}

static int gtphub_gc_peer(struct gtphub_peer *p)
{
	struct gtphub_peer_addr *pa, *npa;
	llist_for_each_entry_safe(pa, npa, &p->addresses, entry) {
		if (gtphub_gc_peer_addr(pa)) {
			gtphub_peer_addr_del(pa);
		}
	}

	/* Note that there's a ref_count in each gtphub_peer_port instance
	 * listed within p->addresses, referenced by TEI mappings from
	 * hub->tei_map. As long as those don't expire, this peer will stay. */

	return llist_empty(&p->addresses)
		&& nr_map_empty(&p->seq_map);
}

static void gtphub_gc_bind(struct gtphub_bind *b)
{
	struct gtphub_peer *p, *n;
	llist_for_each_entry_safe(p, n, &b->peers, entry) {
		if (gtphub_gc_peer(p)) {
			gtphub_peer_del(p);
		}
	}
}

void gtphub_gc(struct gtphub *hub, time_t now)
{
	int expired;
	expired = expiry_tick(&hub->expire_quickly, now);
	expired += expiry_tick(&hub->expire_slowly, now);

	/* ... */

	if (expired) {
		int s, p;
		for_each_side_and_plane(s, p) {
			gtphub_gc_bind(&hub->to_gsns[s][p]);
		}
	}
}

static void gtphub_gc_cb(void *data)
{
	struct gtphub *hub = data;
	gtphub_gc(hub, gtphub_now());
	osmo_timer_schedule(&hub->gc_timer, GTPH_GC_TICK_SECONDS, 0);
}

static void gtphub_gc_start(struct gtphub *hub)
{
	osmo_timer_setup(&hub->gc_timer, gtphub_gc_cb, hub);
	osmo_timer_schedule(&hub->gc_timer, GTPH_GC_TICK_SECONDS, 0);
}

/* called by unit tests */
void gtphub_init(struct gtphub *hub)
{
	gtphub_zero(hub);

	INIT_LLIST_HEAD(&hub->tunnels);
	INIT_LLIST_HEAD(&hub->pending_deletes);

	expiry_init(&hub->expire_quickly, GTPH_EXPIRE_QUICKLY_SECS);
	expiry_init(&hub->expire_slowly, GTPH_EXPIRE_SLOWLY_MINUTES * 60);

	nr_pool_init(&hub->tei_pool, 1, 0xffffffff);

	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		gtphub_bind_init(&hub->to_gsns[side_idx][plane_idx], CTR_IDX_HUB(side_idx, plane_idx));
	}

	hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_CTRL].label = "SGSN Ctrl";
	hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].label = "GGSN Ctrl";
	hub->to_gsns[GTPH_SIDE_SGSN][GTPH_PLANE_USER].label = "SGSN User";
	hub->to_gsns[GTPH_SIDE_GGSN][GTPH_PLANE_USER].label = "GGSN User";
}

/* For the test suite, this is kept separate from gtphub_stop(), which also
 * closes sockets. The test suite avoids using sockets and would cause
 * segfaults when trying to close uninitialized ofds. */
void gtphub_free(struct gtphub *hub)
{
	/* By expiring all mappings, a garbage collection should free
	 * everything else. A gtphub_bind_free() will assert that everything is
	 * indeed empty. */
	expiry_clear(&hub->expire_quickly);
	expiry_clear(&hub->expire_slowly);

	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		gtphub_gc_bind(&hub->to_gsns[side_idx][plane_idx]);
		gtphub_bind_free(&hub->to_gsns[side_idx][plane_idx]);
	}
}

void gtphub_stop(struct gtphub *hub)
{
	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		gtphub_bind_stop(&hub->to_gsns[side_idx][plane_idx]);
	}
	gtphub_free(hub);
}

static int gtphub_make_proxy(struct gtphub *hub,
			     struct gtphub_peer_port **pp,
			     struct gtphub_bind *bind,
			     const struct gtphub_cfg_addr *addr)
{
	if (!addr->addr_str)
		return 0;

	struct gsn_addr gsna;
	if (gsn_addr_from_str(&gsna, addr->addr_str) != 0)
		return -1;

	*pp = gtphub_port_have(hub, bind, &gsna, addr->port);

	/* This is *the* proxy. Make sure it is never expired. */
	gtphub_port_ref_count_inc(*pp);
	return 0;
}

int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg,
		 uint8_t restart_counter)
{
	gtphub_init(hub);

	hub->restart_counter = restart_counter;
	hub->sgsn_use_sender = cfg->sgsn_use_sender? 1 : 0;

	/* If a Ctrl plane proxy is configured, ares will never be used. */
	if (!cfg->proxy[GTPH_SIDE_GGSN][GTPH_PLANE_CTRL].addr_str) {
		if (gtphub_ares_init(hub) != 0) {
			LOG(LOGL_FATAL, "Failed to initialize ares\n");
			return -1;
		}
	}

	int side_idx;
	int plane_idx;
	for_each_side_and_plane(side_idx, plane_idx) {
		int rc;
		rc = gtphub_bind_start(&hub->to_gsns[side_idx][plane_idx],
				       &cfg->to_gsns[side_idx][plane_idx],
				       (side_idx == GTPH_SIDE_SGSN)
					       ? from_sgsns_read_cb
					       : from_ggsns_read_cb,
				       hub, plane_idx);
		if (rc) {
			LOG(LOGL_FATAL, "Failed to bind for %ss (%s)\n",
			    gtphub_side_idx_names[side_idx],
			    gtphub_plane_idx_names[plane_idx]);
			return rc;
		}
	}

	for_each_side_and_plane(side_idx, plane_idx) {
		if (gtphub_make_proxy(hub,
				      &hub->proxy[side_idx][plane_idx],
				      &hub->to_gsns[side_idx][plane_idx],
				      &cfg->proxy[side_idx][plane_idx])
		    != 0) {
			LOG(LOGL_FATAL, "Cannot configure %s proxy"
			    " %s port %d.\n",
			    gtphub_side_idx_names[side_idx],
			    cfg->proxy[side_idx][plane_idx].addr_str,
			    (int)cfg->proxy[side_idx][plane_idx].port);
			return -1;
		}
	}

	for_each_side_and_plane(side_idx, plane_idx) {
		if (hub->proxy[side_idx][plane_idx])
			LOG(LOGL_NOTICE, "Using %s %s proxy %s\n",
			    gtphub_side_idx_names[side_idx],
			    gtphub_plane_idx_names[plane_idx],
			    gtphub_port_str(hub->proxy[side_idx][plane_idx]));
	}

	if (hub->sgsn_use_sender)
		LOG(LOGL_NOTICE, "Using sender address and port for SGSN instead of GSN Addr IE and default ports.\n");

	gtphub_gc_start(hub);
	return 0;
}

static struct gtphub_peer_addr *gtphub_peer_find_addr(const struct gtphub_peer *peer,
						      const struct gsn_addr *addr)
{
	struct gtphub_peer_addr *a;
	llist_for_each_entry(a, &peer->addresses, entry) {
		if (gsn_addr_same(&a->addr, addr))
			return a;
	}
	return NULL;
}

static struct gtphub_peer_port *gtphub_addr_find_port(const struct gtphub_peer_addr *a,
						      uint16_t port)
{
	OSMO_ASSERT(port);
	struct gtphub_peer_port *pp;
	llist_for_each_entry(pp, &a->ports, entry) {
		if (pp->port == port)
			return pp;
	}
	return NULL;
}

static struct gtphub_peer_addr *gtphub_addr_find(const struct gtphub_bind *bind,
						 const struct gsn_addr *addr)
{
	struct gtphub_peer *peer;
	llist_for_each_entry(peer, &bind->peers, entry) {
		struct gtphub_peer_addr *a = gtphub_peer_find_addr(peer, addr);
		if (a)
			return a;
	}
	return NULL;
}

static struct gtphub_peer_port *gtphub_port_find(const struct gtphub_bind *bind,
						 const struct gsn_addr *addr,
						 uint16_t port)
{
	struct gtphub_peer_addr *a = gtphub_addr_find(bind, addr);
	if (!a)
		return NULL;
	return gtphub_addr_find_port(a, port);
}

struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
					     const struct osmo_sockaddr *addr)
{
	struct gsn_addr gsna;
	uint16_t port;
	if (gsn_addr_from_sockaddr(&gsna, &port, addr) != 0)
		return NULL;

	return gtphub_port_find(bind, &gsna, port);
}

static struct gtphub_peer *gtphub_peer_new(struct gtphub *hub,
					   struct gtphub_bind *bind)
{
	struct gtphub_peer *peer = talloc_zero(osmo_gtphub_ctx,
					       struct gtphub_peer);
	OSMO_ASSERT(peer);

	INIT_LLIST_HEAD(&peer->addresses);

	nr_pool_init(&peer->seq_pool, 0, 0xffff);
	nr_map_init(&peer->seq_map, &peer->seq_pool, &hub->expire_quickly);

	/* TODO use something random to pick the initial sequence nr.
	   0x6d31 produces the ASCII character sequence 'm1', currently used in
	   gtphub_nc_test.sh. */
	peer->seq_pool.last_nr = 0x6d31 - 1;

	llist_add(&peer->entry, &bind->peers);
	return peer;
}

static struct gtphub_peer_addr *gtphub_peer_add_addr(struct gtphub_peer *peer,
						     const struct gsn_addr *addr)
{
	struct gtphub_peer_addr *a;
	a = talloc_zero(osmo_gtphub_ctx, struct gtphub_peer_addr);
	OSMO_ASSERT(a);
	a->peer = peer;
	gsn_addr_copy(&a->addr, addr);
	INIT_LLIST_HEAD(&a->ports);
	llist_add(&a->entry, &peer->addresses);

	return a;
}

static struct gtphub_peer_addr *gtphub_addr_have(struct gtphub *hub,
						 struct gtphub_bind *bind,
						 const struct gsn_addr *addr)
{
	struct gtphub_peer_addr *a = gtphub_addr_find(bind, addr);
	if (a)
		return a;

	/* If we haven't found an address, that means we need to create an
	 * 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);

	a = gtphub_peer_add_addr(peer, addr);
	
	LOG(LOGL_DEBUG, "New peer address: %s %s\n",
	    bind->label,
	    gsn_addr_to_str(&a->addr));

	return a;
}

static struct gtphub_peer_port *gtphub_addr_add_port(struct gtphub_peer_addr *a,
						     uint16_t port)
{
	struct gtphub_peer_port *pp;

	pp = talloc_zero(osmo_gtphub_ctx, struct gtphub_peer_port);
	OSMO_ASSERT(pp);
	pp->peer_addr = a;
	pp->port = port;
	pp->last_restart_count = -1;

	if (gsn_addr_to_sockaddr(&a->addr, port, &pp->sa) != 0) {
		talloc_free(pp);
		return NULL;
	}

	pp->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
					       &gtphub_ctrg_io_desc, port);
	if (!pp->counters_io) {
		LOG(LOGL_ERROR, "Failed to allocate rate counters for %s:%u\n", gsn_addr_to_str(&a->addr), port);
		talloc_free(pp);
		return NULL;
	}

	llist_add(&pp->entry, &a->ports);

	LOG(LOGL_DEBUG, "New peer port: %s port %d\n",
	    gsn_addr_to_str(&a->addr),
	    (int)port);

	return pp;
}

struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub,
					  struct gtphub_bind *bind,
					  const struct gsn_addr *addr,
					  uint16_t port)
{
	struct gtphub_peer_addr *a = gtphub_addr_have(hub, bind, addr);

	struct gtphub_peer_port *pp = gtphub_addr_find_port(a, port);
	if (pp)
		return pp;

	return gtphub_addr_add_port(a, port);
}

/* Find a GGSN peer with a matching address. If the address is known but the
 * port not, create a new port for that peer address. */
struct gtphub_peer_port *gtphub_known_addr_have_port(const struct gtphub_bind *bind,
						     const struct osmo_sockaddr *addr)
{
	struct gtphub_peer_addr *pa;
	struct gtphub_peer_port *pp;

	struct gsn_addr gsna;
	uint16_t port;
	int rc = gsn_addr_from_sockaddr(&gsna, &port, addr);
	if (rc < 0)
		LOG(LOGL_ERROR, "%s(): failed to obtain GSN address\n", __func__);

	pa = gtphub_addr_find(bind, &gsna);
	if (!pa)
		return NULL;

	pp = gtphub_addr_find_port(pa, port);

	if (!pp)
		pp = gtphub_addr_add_port(pa, port);

	return pp;
}


/* Return 0 if the message in p is not applicable for GGSN resolution, -1 if
 * resolution should be possible but failed, and 1 if resolution was
 * successful. *pp will be set to NULL if <1 is returned. */
static int gtphub_resolve_ggsn(struct gtphub *hub,
			       struct gtp_packet_desc *p,
			       struct gtphub_peer_port **pp)
{
	*pp = NULL;

	/* TODO determine from message type whether IEs should be present? */

	int rc;
	const char *imsi_str;
	rc = get_ie_imsi_str(p->ie, 0, &imsi_str);
	if (rc < 1)
		return rc;
	OSMO_ASSERT(imsi_str);

	const char *apn_str;
	rc = get_ie_apn_str(p->ie, &apn_str);
	if (rc < 1)
		return rc;
	OSMO_ASSERT(apn_str);

	*pp = gtphub_resolve_ggsn_addr(hub, imsi_str, apn_str);
	return (*pp)? 1 : -1;
}


/* TODO move to osmocom/core/socket.c ? */
/* use this in osmo_sock_init() to remove dup. */
/* Internal: call getaddrinfo for osmo_sockaddr_init(). The caller is required
   to call freeaddrinfo(*result), iff zero is returned. */
static int _osmo_getaddrinfo(struct addrinfo **result,
			     uint16_t family, uint16_t type, uint8_t proto,
			     const char *host, uint16_t port)
{
	struct addrinfo hints;
	char portbuf[16];

	sprintf(portbuf, "%u", port);
	memset(&hints, '\0', sizeof(struct addrinfo));
	hints.ai_family = family;
	if (type == SOCK_RAW) {
		/* Workaround for glibc, that returns EAI_SERVICE (-8) if
		 * SOCK_RAW and IPPROTO_GRE is used.
		 */
		hints.ai_socktype = SOCK_DGRAM;
		hints.ai_protocol = IPPROTO_UDP;
	} else {
		hints.ai_socktype = type;
		hints.ai_protocol = proto;
	}

	return getaddrinfo(host, portbuf, &hints, result);
}

/* TODO move to osmocom/core/socket.c ? */
int osmo_sockaddr_init(struct osmo_sockaddr *addr,
		       uint16_t family, uint16_t type, uint8_t proto,
		       const char *host, uint16_t port)
{
	struct addrinfo *res;
	int rc;
	rc = _osmo_getaddrinfo(&res, family, type, proto, host, port);

	if (rc != 0) {
		LOG(LOGL_ERROR, "getaddrinfo returned error %d\n", (int)rc);
		return -EINVAL;
	}

	OSMO_ASSERT(res->ai_addrlen <= sizeof(addr->a));
	memcpy(&addr->a, res->ai_addr, res->ai_addrlen);
	addr->l = res->ai_addrlen;
	freeaddrinfo(res);

	return 0;
}

int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
			  char *port_str, size_t port_str_len,
			  const struct osmo_sockaddr *addr,
			  int flags)
{
       int rc;

       if ((addr->l < 1) || (addr->l > sizeof(addr->a))) {
	       LOGP(DGTPHUB, LOGL_ERROR, "Invalid address size: %d\n", addr->l);
	       return -1;
       }

       if (addr->l > sizeof(addr->a)) {
	       LOGP(DGTPHUB, LOGL_ERROR, "Invalid address: too long: %d\n",
		    addr->l);
	       return -1;
       }

       rc = getnameinfo((struct sockaddr*)&addr->a, addr->l,
			addr_str, addr_str_len,
			port_str, port_str_len,
			flags);

       if (rc)
	       LOGP(DGTPHUB, LOGL_ERROR, "Invalid address: %s: %s\n",
		    gai_strerror(rc), osmo_hexdump((uint8_t*)&addr->a,
						   addr->l));

       return rc;
}

const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
				  char *buf, size_t buf_len)
{
	const int portbuf_len = 6;
	OSMO_ASSERT(buf_len > portbuf_len);
	char *portbuf = buf + buf_len - portbuf_len;
	buf_len -= portbuf_len;
	if (osmo_sockaddr_to_strs(buf, buf_len,
				  portbuf, portbuf_len,
				  addr,
				  NI_NUMERICHOST | NI_NUMERICSERV))
		return NULL;

	char *pos = buf + strnlen(buf, buf_len-1);
	size_t len = buf_len - (pos - buf);

	snprintf(pos, len, " port %s", portbuf);
	buf[buf_len-1] = '\0';

	return buf;
}

const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr)
{
	static char buf[256];
	const char *result = osmo_sockaddr_to_strb(addr, buf, sizeof(buf));
	if (! result)
		return "(invalid)";
	return result;
}

int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
		      const struct osmo_sockaddr *b)
{
	if (a == b)
		return 0;
	if (!a)
		return -1;
	if (!b)
		return 1;
	if (a->l != b->l) {
		/* Lengths are not the same, but determine the order. Will
		 * anyone ever sort a list by osmo_sockaddr though...? */
		int cmp = memcmp(&a->a, &b->a, (a->l < b->l)? a->l : b->l);
		if (cmp == 0) {
			if (a->l < b->l)
				return -1;
			else
				return 1;
		}
		return cmp;
	}
	return memcmp(&a->a, &b->a, a->l);
}

void osmo_sockaddr_copy(struct osmo_sockaddr *dst,
			const struct osmo_sockaddr *src)
{
	OSMO_ASSERT(src->l <= sizeof(dst->a));
	memcpy(&dst->a, &src->a, src->l);
	dst->l = src->l;
}
