From 5e6d679df39e5e20b55ef24754a4e6310c9bcad2 Mon Sep 17 00:00:00 2001 From: Jacob Erlbeck Date: Mon, 14 Oct 2013 22:06:48 +0200 Subject: gb: Fix gprs_ns_rx_reset to not create NS-VC duplicates Under special circumstances (see below) receiving a NS-RESET leads to duplicated NS-VC entries. This happens when the source port of a NS-VC changes to a new one that has already been used by another NS-VC. This patch changes gprs_ns_rx_reset() to check for this case and to use the existing NS-VC object. The NS-VC object that was associated with the source address before is detached from this source but kept in the NS-VC list so that it can be reattached when a correspondent NS-RESET is received later on. Meanwhile it will have a cleared link layer address which will not match a real link info. A new counter NS_CTR_REPLACED is incremented each time when the NS-VC object is replacing another one. A new signal S_NS_REPLACED is added which gets dispatched in this case, too. Another new counter NS_CTR_NSEI_CHG is incremented each time when the NSEI of a NS-VC object (with fixed NSVCI) changes. Ticket: OW#874 Sponsored-by: On-Waves ehf --- tests/gb/gprs_ns_test.c | 28 +++++++++++++++++++++++++++- tests/gb/gprs_ns_test.ok | 10 ++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/gb/gprs_ns_test.c b/tests/gb/gprs_ns_test.c index 1474fd4d..d7b769df 100644 --- a/tests/gb/gprs_ns_test.c +++ b/tests/gb/gprs_ns_test.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -113,7 +114,7 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, if (!real_sendto) real_sendto = dlsym(RTLD_NEXT, "sendto"); - if (sockfd != 0xdead && ((struct sockaddr_in *)dest_addr)->sin_addr.s_addr != htonl(0x01020304)) + if (((struct sockaddr_in *)dest_addr)->sin_addr.s_addr != htonl(0x01020304)) return real_sendto(sockfd, buf, len, flags, dest_addr, addrlen); printf("RESPONSE, msg length %d\n%s\n\n", len, osmo_hexdump(buf, len)); @@ -121,6 +122,21 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, return len; } +static void dump_rate_ctr_group(FILE *stream, const char *prefix, + struct rate_ctr_group *ctrg) +{ + unsigned int i; + + for (i = 0; i < ctrg->desc->num_ctr; i++) { + struct rate_ctr *ctr = &ctrg->ctr[i]; + if (ctr->current && !strchr(ctrg->desc->ctr_desc[i].name, '.')) + fprintf(stream, " %s%s: %llu%s", + prefix, ctrg->desc->ctr_desc[i].description, + (long long)ctr->current, + "\n"); + }; +} + /* Signal handler for signals from NS layer */ static int test_signal(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data) @@ -155,6 +171,15 @@ static int test_signal(unsigned int subsys, unsigned int signal, gprs_ns_ll_str(nssd->nsvc)); break; + case S_NS_REPLACED: + printf("==> got signal NS_REPLACED: 0x%04x/%s", + nssd->nsvc->nsvci, + gprs_ns_ll_str(nssd->nsvc)); + printf(" -> 0x%04x/%s\n", + nssd->old_nsvc->nsvci, + gprs_ns_ll_str(nssd->old_nsvc)); + break; + default: printf("==> got signal %d, NS-VC 0x%04x/%s\n", signal, nssd->nsvc->nsvci, @@ -203,6 +228,7 @@ static void gprs_dump_nsi(struct gprs_ns_inst *nsi) nsvc->nsvci, nsvc->nsei, ntohl(peer->sin_addr.s_addr), ntohs(peer->sin_port) ); + dump_rate_ctr_group(stdout, " ", nsvc->ctrg); } printf("\n"); } diff --git a/tests/gb/gprs_ns_test.ok b/tests/gb/gprs_ns_test.ok index 01b1bc91..7be84ef7 100644 --- a/tests/gb/gprs_ns_test.ok +++ b/tests/gb/gprs_ns_test.ok @@ -91,12 +91,14 @@ result (RESET) = 9 Current NS-VCIs: VCI 0x3344, NSEI 0x1122, peer 0x01020304:3333 VCI 0x1122, NSEI 0x3344, peer 0x01020304:4444 + NS-VC changed NSEI : 1 --- Peer port 3333, RESET, VCI is changed back --- PROCESSING RESET from 0x01020304:3333 02 00 81 01 01 82 11 22 04 82 11 22 +==> got signal NS_REPLACED: 0x1122/1.2.3.4:4444 -> 0x3344/1.2.3.4:3333 ==> got signal NS_RESET, NS-VC 0x1122/1.2.3.4:3333 RESPONSE, msg length 9 03 01 82 11 22 04 82 11 22 @@ -107,8 +109,10 @@ RESPONSE, msg length 1 result (RESET) = 9 Current NS-VCIs: + VCI 0x3344, NSEI 0x1122, peer 0x00000000:0 VCI 0x1122, NSEI 0x1122, peer 0x01020304:3333 - VCI 0x1122, NSEI 0x3344, peer 0x01020304:4444 + NS-VC replaced other count: 1 + NS-VC changed NSEI : 2 --- Peer port 4444, RESET, NSEI is changed back --- @@ -125,8 +129,10 @@ RESPONSE, msg length 1 result (RESET) = 9 Current NS-VCIs: - VCI 0x1122, NSEI 0x1122, peer 0x01020304:3333 + VCI 0x3344, NSEI 0x1122, peer 0x00000000:0 VCI 0x1122, NSEI 0x1122, peer 0x01020304:4444 + NS-VC replaced other count: 1 + NS-VC changed NSEI : 2 ===== NS protocol test END -- cgit v1.2.3