diff mbox

[2/3] gtphub: fix number map range for TEIs.

Message ID 1447767527-27316-2-git-send-email-nhofmeyr@sysmocom.de
State Changes Requested
Headers show

Commit Message

Neels Hofmeyr Nov. 17, 2015, 1:38 p.m. UTC
Use unsigned int for nr_map, just large enough to fit the TEI space.
Adjust log output formats and casts accordingly.

Fixes: TEIs are uint32_t, but the nr_map so far used int. This would cause TEIs
from 0x80000000 on to be handled and printed as a negative value.

Sponsored-by: On-Waves ehi
---
 openbsc/include/openbsc/gtphub.h   |  2 +-
 openbsc/src/gprs/gtphub.c          | 15 ++++++++-------
 openbsc/tests/gtphub/gtphub_test.c |  6 +++---
 3 files changed, 12 insertions(+), 11 deletions(-)

Comments

Holger Freyther Nov. 25, 2015, 7:53 p.m. UTC | #1
> On 17 Nov 2015, at 14:38, Neels Hofmeyr <nhofmeyr@sysmocom.de> wrote:
> 
> Use unsigned int for nr_map, just large enough to fit the TEI space.
> Adjust log output formats and casts accordingly.
> 
> Fixes: TEIs are uint32_t, but the nr_map so far used int. This would cause TEIs
> from 0x80000000 on to be handled and printed as a negative value.


good!


> -typedef int nr_t;
> +typedef unsigned int nr_t;

use uint32_t here then? and "nr_t" is that clear it refers to a tei?


> +	    (unsigned int)nrm->orig, (unsigned int)nrm->repl);

What is the explicit casting about?

holger
Neels Hofmeyr Nov. 26, 2015, 4:29 p.m. UTC | #2
On Wed, Nov 25, 2015 at 08:53:45PM +0100, Holger Freyther wrote:
> > -typedef int nr_t;
> > +typedef unsigned int nr_t;
> 
> use uint32_t here then? and "nr_t" is that clear it refers to a tei?

nr_map is used for both sequence numbers and TEIs with different range
settings. Sequence numbers range from 0..ffff and TEIs from 1..ffffffff.
So nr_t is intended to be more general, but since gtphub is the only scope
using it, unsigned int is enough to fit both number spaces (assuming int
size will never be less than 32 bits...). So nr_t refers to a TEI as soon
as a nr_pool is *used* for a TEI.

> > +	    (unsigned int)nrm->orig, (unsigned int)nrm->repl);
> 
> What is the explicit casting about?

To print values 80000000..ffffffff as positive numbers, the printf format
is using '%u'. Casting to unsigned int it is my preferred way of making
sure the argument matches the printf format...

Might not be necessary, but erases all doubt about intention or type
sizes.

~Neels
Jacob Erlbeck Nov. 27, 2015, 8:38 a.m. UTC | #3
On 26.11.2015 17:29, Neels Hofmeyr wrote:
> On Wed, Nov 25, 2015 at 08:53:45PM +0100, Holger Freyther wrote:
> 
>>> +	    (unsigned int)nrm->orig, (unsigned int)nrm->repl);
>>
>> What is the explicit casting about?
> 
> To print values 80000000..ffffffff as positive numbers, the printf format
> is using '%u'. Casting to unsigned int it is my preferred way of making
> sure the argument matches the printf format...
> 
> Might not be necessary, but erases all doubt about intention or type
> sizes.

As far as I understand the C99 specification, this not necessary. IMO
the make the code less readable and the hinder the compiler and tools
like coverity to find certain bugs, e.g. if someone raised the type of
nmr->orig to 'long long' for some reason, he/she wouldn't get a warning
from the tools.

Here is the definition of "integer promotions":

  §6.3.1.1 (2): "If an int can represent all values of the original
type, the value is converted to an int; otherwise, it is converted to an
unsigned int. These are called the integer promotions. All other types
are unchanged by the integer promotions."

Here is the definition of "default argument promotions":

  §6.5.2.2 (6): "If the expression that denotes the called function has
a type that does not include a prototype, the integer promotions are
performed on each argument, and arguments that have type float are
promoted to double. These are called the default argument promotions. ..."

And finally, these have to be applied to the trailing arguments or printf:

  §6.5.2.2 (7): "... The ellipsis notation in a function prototype
declarator causes argument type conversion to stop after the last
declared parameter. The default argument promotions are performed on
trailing arguments."

Jacob
diff mbox

Patch

diff --git a/openbsc/include/openbsc/gtphub.h b/openbsc/include/openbsc/gtphub.h
index 68cf90e..c43a328 100644
--- a/openbsc/include/openbsc/gtphub.h
+++ b/openbsc/include/openbsc/gtphub.h
@@ -249,7 +249,7 @@  int expiry_tick(struct expiry *exq, time_t now);
  * NULL, no deallocation will be done (allowing statically allocated entries).
  */
 
-typedef int nr_t;
+typedef unsigned int nr_t;
 
 /* Generator for unused numbers. So far this counts upwards from zero, but the
  * implementation may change in the future. Treat this like an opaque struct.
diff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c
index 22da9a3..7c7f693 100644
--- a/openbsc/src/gprs/gtphub.c
+++ b/openbsc/src/gprs/gtphub.c
@@ -914,10 +914,10 @@  static void gtphub_mapping_del_cb(struct expiring_item *expi)
 	/* Just for log */
 	struct gtphub_peer_port *from = nrm->origin;
 	OSMO_ASSERT(from);
-	LOG(LOGL_DEBUG, "expired: %d: nr mapping from %s: %d->%d\n",
+	LOG(LOGL_DEBUG, "expired: %d: nr mapping from %s: %u->%u\n",
 	    (int)nrm->expiry_entry.expiry,
 	    gtphub_port_str(from),
-	    (int)nrm->orig, (int)nrm->repl);
+	    (unsigned int)nrm->orig, (unsigned int)nrm->repl);
 
 	gtphub_port_ref_count_dec(from);
 
@@ -960,10 +960,10 @@  static uint32_t gtphub_tei_mapping_have(struct gtphub *hub,
 {
 	struct nr_mapping *nrm = gtphub_mapping_have(&hub->tei_map[plane_idx],
 						     from, orig_tei, now);
-	LOG(LOGL_DEBUG, "New %s TEI: (from %s, TEI %d) <-- TEI %d\n",
+	LOG(LOGL_DEBUG, "New %s TEI: (from %s, TEI %u) <-- TEI %u\n",
 	    gtphub_plane_idx_names[plane_idx],
 	    gtphub_port_str(from),
-	    (int)orig_tei, (int)nrm->repl);
+	    (unsigned int)orig_tei, (unsigned int)nrm->repl);
 
 	return (uint32_t)nrm->repl;
 }
@@ -1115,8 +1115,9 @@  static int gtphub_unmap_header_tei(struct gtphub_peer_port **to_port_p,
 	uint32_t unmapped_tei = nrm->orig;
 	set_tei(p, unmapped_tei);
 
-	LOG(LOGL_DEBUG, "Unmapped TEI coming from %s: %d -> %d (to %s)\n",
-	    gtphub_port_str(from_port), tei, unmapped_tei,
+	LOG(LOGL_DEBUG, "Unmapped TEI coming from %s: %u -> %u (to %s)\n",
+	    gtphub_port_str(from_port),
+	    (unsigned int)tei, (unsigned int)unmapped_tei,
 	    gtphub_port_str2(to_port));
 
 	*to_port_p = to_port;
@@ -1309,7 +1310,7 @@  static int gtphub_unmap(struct gtphub *hub,
 		    gtphub_peer_str(from_peer),
 		    (int)p->seq,
 		    gtphub_port_str(from_seq),
-		    (int)p->header_tei,
+		    (unsigned int)p->header_tei,
 		    gtphub_port_str2(from_tei)
 		   );
 	}
diff --git a/openbsc/tests/gtphub/gtphub_test.c b/openbsc/tests/gtphub/gtphub_test.c
index 8434f61..4e22ac7 100644
--- a/openbsc/tests/gtphub/gtphub_test.c
+++ b/openbsc/tests/gtphub/gtphub_test.c
@@ -233,9 +233,9 @@  static int nr_map_is(struct nr_map *map, const char *str)
 	size_t len = sizeof(buf);
 	struct nr_mapping *m;
 	llist_for_each_entry(m, &map->mappings, entry) {
-		size_t wrote = snprintf(pos, len, "(%d->%d@%d), ",
-					(int)m->orig,
-					(int)m->repl,
+		size_t wrote = snprintf(pos, len, "(%u->%u@%d), ",
+					m->orig,
+					m->repl,
 					(int)m->expiry_entry.expiry);
 		OSMO_ASSERT(wrote < len);
 		pos += wrote;