2015-09-24 15:32:30 +00:00
|
|
|
/* GTP Hub Implementation */
|
|
|
|
|
|
|
|
/* (C) 2015 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
2015-11-18 16:53:00 +00:00
|
|
|
* gtphub_ares.c.
|
|
|
|
*
|
|
|
|
* This file is kept separate so that these functions can be wrapped for
|
|
|
|
* gtphub_test.c. When a function and its callers are in the same compilational
|
|
|
|
* unit, the wrappability may be optimized away.
|
2015-09-24 15:32:30 +00:00
|
|
|
*
|
|
|
|
* 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>
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
#include <unistd.h>
|
2015-09-24 15:32:30 +00:00
|
|
|
|
|
|
|
#include <openbsc/gtphub.h>
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
#include <openbsc/debug.h>
|
|
|
|
|
2015-09-24 15:32:30 +00:00
|
|
|
#include <osmocom/core/utils.h>
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
#include <osmocom/gsm/apn.h>
|
|
|
|
|
|
|
|
/* TODO split GRX ares from sgsn into a separate struct and allow use without
|
|
|
|
* globals. */
|
|
|
|
#include <openbsc/sgsn.h>
|
|
|
|
extern struct sgsn_instance *sgsn;
|
|
|
|
|
|
|
|
struct sgsn_instance sgsn_inst = { 0 };
|
|
|
|
struct sgsn_instance *sgsn = &sgsn_inst;
|
|
|
|
|
|
|
|
extern void *osmo_gtphub_ctx;
|
|
|
|
|
|
|
|
int gtphub_ares_init(struct gtphub *hub)
|
|
|
|
{
|
|
|
|
return sgsn_ares_init(sgsn);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ggsn_lookup {
|
|
|
|
struct llist_head entry;
|
|
|
|
struct expiring_item expiry_entry;
|
|
|
|
|
|
|
|
struct gtphub *hub;
|
|
|
|
|
|
|
|
char imsi_str[GSM_IMSI_LENGTH];
|
|
|
|
char apn_ni_str[GSM_APN_LENGTH];
|
|
|
|
char apn_oi_str[GSM_APN_LENGTH];
|
|
|
|
int have_3dig_mnc;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int start_ares_query(struct ggsn_lookup *lookup);
|
2015-09-24 15:32:30 +00:00
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
static void ggsn_lookup_cb(void *arg, int status, int timeouts,
|
|
|
|
struct hostent *hostent)
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
{
|
|
|
|
struct ggsn_lookup *lookup = arg;
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "ggsn_lookup_cb(%p / %p)", lookup,
|
|
|
|
&lookup->expiry_entry);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
|
|
|
if (status != ARES_SUCCESS) {
|
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "DNS query failed.\n");
|
|
|
|
|
|
|
|
/* Need to try with three digits now */
|
|
|
|
if (!lookup->have_3dig_mnc) {
|
|
|
|
lookup->have_3dig_mnc = 1;
|
|
|
|
if (start_ares_query(lookup) == 0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "Failed to resolve GGSN. (%p)\n",
|
|
|
|
lookup);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
goto remove_from_queue;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct gsn_addr resolved_addr;
|
|
|
|
if (hostent->h_length > sizeof(resolved_addr.buf)) {
|
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "Addr size too large: %d > %d\n",
|
|
|
|
(int)hostent->h_length, (int)sizeof(resolved_addr.buf));
|
|
|
|
goto remove_from_queue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the first addr from the list */
|
|
|
|
char *addr0 = hostent->h_addr_list[0];
|
|
|
|
if (!addr0) {
|
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "No host address.\n");
|
|
|
|
goto remove_from_queue;
|
|
|
|
}
|
2015-09-24 15:32:30 +00:00
|
|
|
|
2015-11-11 16:27:01 +00:00
|
|
|
memcpy(resolved_addr.buf, addr0, hostent->h_length);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
resolved_addr.len = hostent->h_length;
|
|
|
|
|
2015-11-11 16:20:42 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "resolved addr %s\n",
|
2015-11-16 13:52:05 +00:00
|
|
|
osmo_hexdump((unsigned char*)&resolved_addr,
|
|
|
|
sizeof(resolved_addr)));
|
2015-11-11 16:20:42 +00:00
|
|
|
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
gtphub_resolved_ggsn(lookup->hub, lookup->apn_oi_str, &resolved_addr,
|
|
|
|
gtphub_now());
|
|
|
|
|
|
|
|
remove_from_queue:
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "Removing GGSN lookup. (%p / %p)\n", lookup,
|
|
|
|
&lookup->expiry_entry);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
expiring_item_del(&lookup->expiry_entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void make_addr_str(struct ggsn_lookup *lookup)
|
2015-09-24 15:32:30 +00:00
|
|
|
{
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
char *apn_oi_str;
|
|
|
|
apn_oi_str = osmo_apn_qualify_from_imsi(lookup->imsi_str,
|
|
|
|
lookup->apn_ni_str,
|
|
|
|
lookup->have_3dig_mnc);
|
|
|
|
strncpy(lookup->apn_oi_str, apn_oi_str, sizeof(lookup->apn_oi_str));
|
|
|
|
lookup->apn_oi_str[sizeof(lookup->apn_oi_str)-1] = '\0';
|
2015-09-24 15:32:30 +00:00
|
|
|
}
|
|
|
|
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
static int start_ares_query(struct ggsn_lookup *lookup)
|
|
|
|
{
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_DEBUG, "Going to query %s (%p / %p)\n",
|
|
|
|
lookup->apn_oi_str, lookup, &lookup->expiry_entry);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
int rc = sgsn_ares_query(sgsn, lookup->apn_oi_str, ggsn_lookup_cb,
|
|
|
|
lookup);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
if (rc != 0)
|
|
|
|
LOGP(DGTPHUB, LOGL_ERROR, "Failed to start ares query.\n");
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ggsn_lookup_del_cb(struct expiring_item *expi)
|
|
|
|
{
|
2015-11-11 16:20:42 +00:00
|
|
|
struct ggsn_lookup *lookup;
|
|
|
|
lookup = container_of(expi, struct ggsn_lookup, expiry_entry);
|
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "ggsn_lookup_del_cb(%p / %p)\n", lookup,
|
|
|
|
expi);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
2015-11-11 16:20:42 +00:00
|
|
|
lookup->expiry_entry.del_cb = 0;
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
expiring_item_del(expi);
|
|
|
|
|
2015-11-11 16:20:42 +00:00
|
|
|
llist_del(&lookup->entry);
|
|
|
|
talloc_free(lookup);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct gtphub_peer_port *gtphub_resolve_ggsn_addr(struct gtphub *hub,
|
|
|
|
const char *imsi_str,
|
|
|
|
const char *apn_ni_str)
|
|
|
|
{
|
2015-11-10 19:32:13 +00:00
|
|
|
OSMO_ASSERT(imsi_str);
|
|
|
|
OSMO_ASSERT(apn_ni_str);
|
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
struct ggsn_lookup *lookup = talloc_zero(osmo_gtphub_ctx,
|
|
|
|
struct ggsn_lookup);
|
2015-11-10 19:32:13 +00:00
|
|
|
OSMO_ASSERT(lookup);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
2015-11-16 13:52:05 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "Request to resolve IMSI"
|
|
|
|
" '%s' with APN-NI '%s' (%p / %p)\n",
|
2015-11-11 16:20:42 +00:00
|
|
|
imsi_str, apn_ni_str, lookup, &lookup->expiry_entry);
|
|
|
|
|
2015-11-11 16:27:01 +00:00
|
|
|
expiring_item_init(&lookup->expiry_entry);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
lookup->hub = hub;
|
|
|
|
|
|
|
|
strncpy(lookup->imsi_str, imsi_str, sizeof(lookup->imsi_str));
|
|
|
|
lookup->imsi_str[sizeof(lookup->imsi_str)-1] = '\0';
|
|
|
|
|
|
|
|
strncpy(lookup->apn_ni_str, apn_ni_str, sizeof(lookup->apn_ni_str));
|
|
|
|
lookup->apn_ni_str[sizeof(lookup->apn_ni_str)-1] = '\0';
|
|
|
|
|
|
|
|
make_addr_str(lookup);
|
|
|
|
|
2015-11-11 16:20:42 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "looking for active queries...\n");
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
struct ggsn_lookup *active;
|
|
|
|
llist_for_each_entry(active, &hub->ggsn_lookups, entry) {
|
|
|
|
if (strncmp(active->apn_oi_str, lookup->apn_oi_str,
|
|
|
|
sizeof(lookup->apn_oi_str)) == 0) {
|
|
|
|
/* A query already pending. Just tip our hat. */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-11 16:20:42 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "looking for already resolved GGSNs...\n");
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
struct gtphub_resolved_ggsn *resolved;
|
|
|
|
llist_for_each_entry(resolved, &hub->resolved_ggsns, entry) {
|
|
|
|
if (strncmp(resolved->apn_oi_str, lookup->apn_oi_str,
|
|
|
|
sizeof(lookup->apn_oi_str)) == 0) {
|
|
|
|
/* Already resolved. */
|
|
|
|
return resolved->peer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Kick off a resolution, but so far return nothing. The hope is that
|
|
|
|
* the peer will resend the request (a couple of times), and by then
|
|
|
|
* the GGSN will be resolved. */
|
2015-11-11 16:20:42 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "kick off resolution.\n");
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
|
|
|
llist_add(&lookup->entry, &hub->ggsn_lookups);
|
|
|
|
|
|
|
|
lookup->expiry_entry.del_cb = ggsn_lookup_del_cb;
|
|
|
|
expiry_add(&hub->expire_seq_maps, &lookup->expiry_entry, gtphub_now());
|
|
|
|
|
|
|
|
start_ares_query(lookup);
|
2015-11-11 18:26:09 +00:00
|
|
|
LOGP(DGTPHUB, LOGL_NOTICE, "Resolving %s %s ..."
|
|
|
|
" (Returning failure, hoping for a retry"
|
|
|
|
"once resolution has concluded)\n",
|
|
|
|
imsi_str, apn_ni_str);
|
gtphub: add first bits of GRX ares
For the resolving function, change the function signature to return a
gtphub_peer_port. In consequence, publish two functions concerned with
gtphub_peer_port instances for use in test and gtphub_ext.c.
Add GGSN resolution queue, callback and cache. Simple implementation: if an
SGSN asks for a GGSN, it will first get no answer, and I hope it will ask again
once the GGSN is in the cache.
Within gtphub_ext.c, have a dummy sgsn struct, as the sgsn_ares code currently
depends on it (half the functions pass an sgsn instance pointer around, but the
other half use the global one).
In the unit tests, wrap away the ares initialization so that they can work
without a DNS server around. The netcat test breaks because of this, will
remove it.
Using sgsn_ares, implement the gtphub_resolve_ggsn_addr() function, I hope:
untested.
Minor cosmetics just to see if you're paying attention... ;)
Sponsored-by: On-Waves ehi
2015-11-08 19:34:47 +00:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|