Message ID | 1447767527-27316-2-git-send-email-nhofmeyr@sysmocom.de |
---|---|
State | Changes Requested |
Headers | show |
> 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
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
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 --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;