/* 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 <openbsc/gtphub.h>
#include <openbsc/debug.h>
#include <openbsc/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>


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,
};


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 = gprs_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.\n");
		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)
{
	ZERO_STRUCT(b);

	INIT_LLIST_HEAD(&b->peers);

	b->counters_io = rate_ctr_group_alloc(osmo_gtphub_ctx,
					      &gtphub_ctrg_io_desc, 0);
	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));
	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\n",
	    (int)received, osmo_sockaddr_to_str(from_addr),
	    osmo_hexdump(buf, received));

	return received;
}

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++;
}

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

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;
}

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=%x/U %x=%x)",
	       c->tei_orig, c->tei_repl,
	       u->tei_orig, u->tei_repl);
	return buf;
}

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

	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;
	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 && te->tei_repl))
			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);
}

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,
						       0);
		OSMO_ASSERT(te->counters_io);
	}

	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_endpoint *new_te,
				   struct gtphub_tunnel_endpoint *iterated_te,
				   uint32_t *tei_min,
				   uint32_t *tei_max)
{
	if (new_te->tei_repl != iterated_te->tei_repl)
		return 1;

	/* new_te->tei_repl is already taken. Try to find one out of the known
	 * range. */

	if ((*tei_max) < 0xffffffff) {
		(*tei_max)++;
		new_te->tei_repl = *tei_max;
		return 1;
	} else if ((*tei_min) > 1) {
		(*tei_min)--;
		new_te->tei_repl = *tei_min;
		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;
	int side_idx2;
	int plane_idx2;
	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 != 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:"
				    " peer %s sent %s TEI %x,"
				    " previously used by tunnel %s...\n",
				    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 TEIs assigned to the endpoints are
		 * used anywhere else. */
		for_each_side_and_plane(side_idx, plane_idx) {
			te = &tun->endpoint[side_idx][plane_idx];
			tei_min = (tei_min < te->tei_repl)? tei_min : te->tei_repl;
			tei_max = (tei_max > te->tei_repl)? tei_max : te->tei_repl;

			for_each_side_and_plane(side_idx2, plane_idx2) {
				te2 = &new_tun->endpoint[side_idx2][plane_idx2];
				if (!gtphub_check_mapped_tei(te2, te, &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 ((te_to->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;
	}
	OSMO_ASSERT(*unmapped_from_tun);

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

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

	/* 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. */
		p->tun = tun = gtphub_tunnel_new();
		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->endpoint[other_side_idx(p->side_idx)][GTPH_PLANE_CTRL].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 (plane_idx = 0; plane_idx < 2; 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)) {
			gsn_addr_from_sockaddr(&use_addr, &use_port, &from_ctrl->sa);
		} 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 the"
			    " no TEI has been announced for this tunnel: %s",
			    gtphub_plane_idx_names[plane_idx],
			    gtphub_tunnel_str(tun));
			return -1;
		}

		if (tei_from_ie) {
			/* Create TEI mapping and replace in GTP packet IE */
			uint32_t mapped_tei = nr_pool_next(&hub->tei_pool);

			tun->endpoint[side_idx][plane_idx].tei_orig = tei_from_ie;
			tun->endpoint[side_idx][plane_idx].tei_repl = mapped_tei;
			p->ie[ie_idx]->tv4.v = hton32(mapped_tei);

			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_DEBUG, "Peer has restarted: %s\n",
	    gtphub_port_str(pp));

	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));

			/* 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));

			struct pending_delete *pd;
			pd = pending_delete_new();
			pd->tun = tun;
			pd->teardown_ind = 0xff;
			pd->nsapi = 0;
			llist_add(&pd->entry, &hub->pending_deletes);
			expiry_add(&hub->expire_quickly, &pd->expiry_entry, p->timestamp);

			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);
		}
	}
}

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);
	LOG(LOGL_DEBUG, "%s rx %s from %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));

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

	if (p.rc <= 0) {
		LOG(LOGL_ERROR, "INVALID: dropping GTP packet from %s %s %s\n",
		    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: unknown GGSN peer: %s\n",
			    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: User plane peer was not"
				    "announced by PDP Context: %s\n",
				    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: invalid %s peer: %s\n",
		    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));

	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) {
		LOG(LOGL_ERROR, "No %s to send to. Dropping packet.\n",
		    gtphub_side_idx_names[other_side_idx(side_idx)]);
		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));

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

	/* 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: %d bytes to %s\n",
	    (side_idx == GTPH_SIDE_SGSN)? "-->" : "<--",
	    gtphub_side_idx_names[other_side_idx(side_idx)],
	    (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);

	strncpy(ggsn->apn_oi_str, apn_oi_str, sizeof(ggsn->apn_oi_str));
	ggsn->apn_oi_str[sizeof(ggsn->apn_oi_str) - 1] = '\0';

	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)
{
	hub->gc_timer.cb = gtphub_gc_cb;
	hub->gc_timer.data = 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]);
	}

	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;
	gsn_addr_from_sockaddr(&gsna, &port, addr);
	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, 0);

	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;
	gsn_addr_from_sockaddr(&gsna, &port, addr);

	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;
}
