N3603: incrementing ip::address

413 views
Skip to first unread message

Oliver Kowalke

unread,
Sep 7, 2013, 12:36:10 AM9/7/13
to netwo...@isocpp.org
Hello,

I'd like to suggest an to add operator++()/operator--() to ip::address_v4 and ip::address_v6.

Incrementing an ip-address is not helpful in the context of network I/O but consider a network-aware application which configures the ip-stack of the OS. In such cases you could have some 'configuration rules' (maybe triggered by some legacy applications) like:
'the ip-address of the network-peer is one above/below) the configured ip-address of this system'.
The 'network-peer' might be a another node in a cluster or a hot-stanby-pair ...

At least the software produced by the company I'm working for has such requirements. Of course you could parse the textual representation of an ip-address convert and increment it but this is hackish - at least for IPv6 addresses mistakes can easily made.

Oliver

Arash Partow

unread,
Sep 7, 2013, 2:36:24 AM9/7/13
to netwo...@isocpp.org
On Oliver Kowalke wrote:
> I'd like to suggest an to add operator++()/operator--() to ip::address_v4 and ip::address_v6.
>

Interesting,




> Incrementing an ip-address is not helpful in the context of network I/O but consider
> a network-aware application which configures the ip-stack of the OS. In such cases you
> could have some 'configuration rules' (maybe triggered by some legacy applications) like:
> 'the ip-address of the network-peer is one above/below) the configured ip-address of
> this system'. The 'network-peer' might be a another node in a cluster or a hot-stanby-pair ...
>

Seems like a pretty flakey way to go about determining
peers/resources, why not use one of the many zero-conf techniques out
there... that said I'll bite.


Would there be wrap around? For example, in ipv4, what would a
decrement to the following address of 0.0.0.0 result in?

Would the result of the inc/dec always be a valid address of the same
type? For example, in ipv4, what would an increment to the following
address 223.255.255.255 result in?

Is it intended to become a multicast address, even though it isn't
pre-increment?




> At least the software produced by the company I'm working for has such requirements.
> Of course you could parse the textual representation of an ip-address convert and
> increment it but this is hackish - at least for IPv6 addresses
mistakes can easily
> made.
>

Could you please provide a more detailed description of what it is
you're proposing should happen.





Arash

Oliver Kowalke

unread,
Sep 7, 2013, 6:59:10 AM9/7/13
to networking
> Incrementing an ip-address is not helpful in the context of network I/O but consider
> a network-aware application which configures the ip-stack of the OS. In such cases you
> could have some 'configuration rules' (maybe triggered by some legacy applications) like:
> 'the ip-address of the network-peer is one above/below) the configured ip-address of
> this system'. The 'network-peer' might be a another node in a cluster or a hot-stanby-pair ...
>

Seems like a pretty flakey way to go about determining
peers/resources, why not use one of the many zero-conf techniques out
there... that said I'll bite.

not possible if you have already an application suite (legacy code) which is already shipped to customers
and you have the requirement to develop a new application has to deal with such 'implicit' configuration rules.

 
Would there be wrap around? For example, in ipv4, what would a
decrement to the following address of 0.0.0.0 result in?

Would the result of the inc/dec always be a valid address of the same
type? For example, in ipv4, what would an increment to the following
address 223.255.255.255 result in?

Is it intended to become a multicast address, even though it isn't
pre-increment?

what happened in this cases has to be discussed - I would vote for that the address becomes invalid

 
> At least the software produced by the company I'm working for has such requirements.
> Of course you could parse the textual representation of an ip-address convert and
 > increment it but this is hackish - at least for IPv6 addresses
mistakes can easily
 > made.
>

Could you please provide a more detailed description of what it is
you're proposing should happen.

sorry - I don't get it

Message has been deleted

Oliver Kowalke

unread,
Sep 8, 2013, 4:54:20 AM9/8/13
to netwo...@isocpp.org
Would there be wrap around? For example, in ipv4, what would a
decrement to the following address of 0.0.0.0 result in?

invalid address
 
Would the result of the inc/dec always be a valid address of the same
type? For example, in ipv4, what would an increment to the following
address 223.255.255.255 result in?
 
ip::address_v4 ip = ip::address_v4::from_string("223.255.255.255");
ip.is_multicast() -> 'false'
++ip;
ip.is_mutlicast() -> 'true'
ip.to_string() -> '224.0.0.0'

Is it intended to become a multicast address, even though it isn't
pre-increment?

yes

- bitwise incrementation (IPv4: 32bit, IPv6: 128bit)
- no wrapping at the edges of the range
- special addresses can already be tested by functions like ip::address_v4::is_multiast(), ip::address_6::is_link_local() etc.

to be discussed: how to express an invalid address

Jens Maurer

unread,
Sep 8, 2013, 9:17:04 AM9/8/13
to netwo...@isocpp.org
On 09/07/2013 06:36 AM, Oliver Kowalke wrote:
> I'd like to suggest an to add operator++()/operator--() to
> ip::address_v4 and ip::address_v6.

This sounds like the 0.1% fringe case that I'd like not to
support in the standard.

> Incrementing an ip-address is not helpful in the context of network
> I/O but consider a network-aware application which configures the
> ip-stack of the OS. In such cases you could have some 'configuration
> rules' (maybe triggered by some legacy applications) like: 'the
> ip-address of the network-peer is one above/below) the configured
> ip-address of this system'. The 'network-peer' might be a another
> node in a cluster or a hot-stanby-pair ...

Ok, I understand that's your use case.

> At least the software produced by the company I'm working for has
> such requirements. Of course you could parse the textual
> representation of an ip-address convert and increment it but this is
> hackish - at least for IPv6 addresses mistakes can easily made.

Does the current ip::address class have any way to get at
the bytes of the address, other than conversion to text?
If not, it might be a good idea to add an interface for that.
Adding an increment operation on top of that should be
comparatively easy.

Put differently: What would your "increment" code look like
with the current ip::address interface and with byte-based access
suggested above?

Thanks,
Jens

Ville Voutilainen

unread,
Sep 8, 2013, 9:34:52 AM9/8/13
to netwo...@isocpp.org
On 8 September 2013 16:17, Jens Maurer <Jens....@gmx.net> wrote:
Does the current ip::address class have any way to get at
the bytes of the address, other than conversion to text?

Yes, it has a to_bytes() function that gives an array. Incrementing that
is not directly supported but is not altogether hard, I suppose.


Ville Voutilainen

unread,
Sep 8, 2013, 9:41:00 AM9/8/13
to netwo...@isocpp.org
Oops. ip::address_v4 has to_bytes and to_ulong, ip::address_v6 has to_bytes. ip::address doesn't
have conversions to bytes.

Oliver Kowalke

unread,
Sep 8, 2013, 9:48:38 AM9/8/13
to networking



2013/9/8 Jens Maurer <Jens....@gmx.net>

Does the current ip::address class have any way to get at
the bytes of the address, other than conversion to text?
If not, it might be a good idea to add an interface for that.
Adding an increment operation on top of that should be
comparatively easy.

Put differently: What would your "increment" code look like
with the current ip::address interface and with byte-based access
suggested above?

I would add the operators for address_v4 and address_v6 not address.

address_v4:
pre-increment operator: casting internal representation (in_addr) to u_long and increment by one

address_v6:
pre-increment operator: internal representation in6_addr is an array of 16 uint8_t and you have to
check the first least-significant block for overflow (255) if incremented.
if yes set it to zero and check the next block, otherwise increment the block.

Ville Voutilainen

unread,
Sep 8, 2013, 9:53:57 AM9/8/13
to netwo...@isocpp.org
On 8 September 2013 16:48, Oliver Kowalke <oliver....@gmail.com> wrote:



2013/9/8 Jens Maurer <Jens....@gmx.net>
Does the current ip::address class have any way to get at
the bytes of the address, other than conversion to text?
If not, it might be a good idea to add an interface for that.
Adding an increment operation on top of that should be
comparatively easy.

Put differently: What would your "increment" code look like
with the current ip::address interface and with byte-based access
suggested above?

I would add the operators for address_v4 and address_v6 not address.

address_v4:
pre-increment operator: casting internal representation (in_addr) to u_long and increment by one

Well, address_v4 already has a to_ulong, so you can do
address_v4 a1{whatever};
address_v4 a1_incr {++a1.to_ulong()};

Ville Voutilainen

unread,
Sep 8, 2013, 10:08:26 AM9/8/13
to netwo...@isocpp.org
On 8 September 2013 16:17, Jens Maurer <Jens....@gmx.net> wrote:
On 09/07/2013 06:36 AM, Oliver Kowalke wrote:
> I'd like to suggest an to add operator++()/operator--() to
> ip::address_v4 and ip::address_v6.

This sounds like the 0.1% fringe case that I'd like not to
support in the standard.

> Incrementing an ip-address is not helpful in the context of network
> I/O but consider a network-aware application which configures the
> ip-stack of the OS. In such cases you could have some 'configuration
> rules' (maybe triggered by some legacy applications) like: 'the
> ip-address of the network-peer is one above/below) the configured
> ip-address of this system'. The 'network-peer' might be a another
> node in a cluster or a hot-stanby-pair ...

Ok, I understand that's your use case.



I work with all sorts of routers and other networking equipment that deal with address ranges for various
purposes (like ranges of ip addresses that are given out by dhcp), being able to perform arithmetic
operations would be very helpful in manipulating such ranges. address_v4 seems to have sufficient
functionality, address_v6 makes such manipulations quite inconvenient. I'm not sure whether this
is such a fringe case.

Oliver Kowalke

unread,
Sep 8, 2013, 10:21:07 AM9/8/13
to networking
2013/9/8 Ville Voutilainen <ville.vo...@gmail.com>

Well, address_v4 already has a to_ulong, so you can do
address_v4 a1{whatever};
address_v4 a1_incr {++a1.to_ulong()};

yes, for address_v4 it's not that problem, but (IMHO) it's not elegant (at least it adds unnecessary creation of a new address object)

Oliver Kowalke

unread,
Sep 8, 2013, 10:23:28 AM9/8/13
to networking
2013/9/8 Ville Voutilainen <ville.vo...@gmail.com>


I work with all sorts of routers and other networking equipment that deal with address ranges for various
purposes (like ranges of ip addresses that are given out by dhcp), being able to perform arithmetic
operations would be very helpful in manipulating such ranges. address_v4 seems to have sufficient
functionality, address_v6 makes such manipulations quite inconvenient. I'm not sure whether this
is such a fringe case.

fine, another one who want's to use C++'s ip::address(_v4/6) for other purposes than only creating as socket ;)

Ville Voutilainen

unread,
Sep 8, 2013, 10:31:10 AM9/8/13
to netwo...@isocpp.org
Yes, crazy as I am, I think I'd use an address type for manipulating addresses. :D

Jens Maurer

unread,
Sep 8, 2013, 11:06:19 AM9/8/13
to netwo...@isocpp.org
On 09/08/2013 03:48 PM, Oliver Kowalke wrote:
>
>
>
> 2013/9/8 Jens Maurer <Jens....@gmx.net <mailto:Jens....@gmx.net>>
>
> Does the current ip::address class have any way to get at
> the bytes of the address, other than conversion to text?
> If not, it might be a good idea to add an interface for that.
> Adding an increment operation on top of that should be
> comparatively easy.
>
> Put differently: What would your "increment" code look like
> with the current ip::address interface and with byte-based access
> suggested above?
>
>
> I would add the operators for address_v4 and address_v6 not address.

Ok, that's probably a good idea.

However, my question was not about adding the operators (it's obvious
this can be done), but what your current "increment" function looks like,
given the rest of the interface we already have:

ip::address_v4 increment(ip::address_v4)
{
// what's here?
}

> address_v4:
> pre-increment operator: casting internal representation (in_addr) to u_long and increment by one
>
> address_v6:
> pre-increment operator: internal representation in6_addr is an array of 16 uint8_tand you have to
> check the first least-significant block for overflow (255) if incremented.
> if yes set it to zero and check the next block, otherwise increment the block.

Ok. Thanks.

For such a special-purpose application, such an implementation doesn't look overly
burdensome to me. In my opinion, providing ++ and -- for IP addresses by the
standard conveys a message that shouldn't be.

(I'm pretty sure that, if the "increment" function is inline, the compiler will
remove any extra copies that might crop up in the source code.)

Jens

Jens Maurer

unread,
Sep 8, 2013, 11:09:10 AM9/8/13
to netwo...@isocpp.org
On 09/08/2013 04:08 PM, Ville Voutilainen wrote:
> I work with all sorts of routers and other networking equipment that deal with address ranges for various
> purposes (like ranges of ip addresses that are given out by dhcp), being able to perform arithmetic
> operations would be very helpful in manipulating such ranges.

I'm fine with an ip::address_range (v4 and/or v6), but which arithmetic
operations do you need on ip::address, then? Maybe std::less to put them in
a map.

Jens

Daniel Krügler

unread,
Sep 8, 2013, 11:14:15 AM9/8/13
to netwo...@isocpp.org
2013/9/8 Jens Maurer <Jens....@gmx.net>
According to n3603, operator< is provided, therefore std::less works.

- Daniel

Oliver Kowalke

unread,
Sep 8, 2013, 11:52:59 AM9/8/13
to networking

2013/9/8 Jens Maurer <Jens....@gmx.net>

However, my question was not about adding the operators (it's obvious
this can be done), but what your current "increment" function looks like,
given the rest of the interface we already have:

  ip::address_v4 increment(ip::address_v4)
  {
    // what's here?
  }

address_v4 & operator++() {
addr_.s_addr = host_to_network_long( ++static_cast< u_long_type >( network_to_host_long(addr_.s_addr) ) );
return * this;
}

address_v4 operator++(int) {
  address_v4 tmp(  addr_);
  ++(*this);
  return tmp;
}
 

> address_v4:
> pre-increment operator: casting internal representation (in_addr) to u_long and increment by one
>
> address_v6:
> pre-increment operator: internal representation in6_addr is an array of 16 uint8_tand you have to
> check the first least-significant block for overflow (255) if incremented.
> if yes set it to zero and check the next block, otherwise increment the block.

Ok. Thanks.

For such a special-purpose application, such an implementation doesn't look overly
burdensome to me.

I believe that many C++-apps are out there which do more than simply using ip::address for creating sockets, for instance configuring the interfaces, calculating routing-rules, generating IPSec-statements and much more ...
The C++-standard should support the developers of such applications.

Jens Maurer

unread,
Sep 8, 2013, 12:34:27 PM9/8/13
to netwo...@isocpp.org
On 09/08/2013 05:52 PM, Oliver Kowalke wrote:
> I believe that many C++-apps are out there which do more than simply
> using ip::address for creating sockets, for instance configuring the
> interfaces, calculating routing-rules, generating IPSec-statements
> and much more ... The C++-standard should support the developers of
> such applications.

Agreed, but which of those use-cases requires which operations?
When I configure an interface, I can't see why I would use
operator++ absent some special-case hackery as in your case.

And when implementing a tree for routing, operator++ is probably
the least interesting operation for that.

And, for IPsec, where is the need for operator++ there? Which
operation on an address does IPsec need?

Jens


Ville Voutilainen

unread,
Sep 8, 2013, 1:06:12 PM9/8/13
to netwo...@isocpp.org
If I have a range at hand, I don't think I need any. The comparisons are already there.
Perhaps it's indeed better to have an address range rather than a set of seemingly
unrelated raw operations, and I can't actually fathom needing much beyond
"add N addresses to this address, effectively forming the range", "extend the range" (oh well,
this is the same thing as the first one), "suppress the range" and "walk a range somehow".

Oliver Kowalke

unread,
Sep 8, 2013, 1:15:41 PM9/8/13
to networking
2013/9/8 Jens Maurer <Jens....@gmx.net>

Agreed, but which of those use-cases requires which operations?
When I configure an interface, I can't see why I would use
operator++ absent some special-case hackery as in your case.

And when implementing a tree for routing, operator++ is probably
the least interesting operation for that.

And, for IPsec, where is the need for operator++ there? Which
operation on an address does IPsec need?

I tried to express that the C++-address classes should not be
limited to support operations related to establish a socket.

Think on network scanners/intrusion tools etc.

I believe to support advanced network-ops we need a fourth address-class
which deals with prefixes (network segments).

Oliver Kowalke

unread,
Sep 8, 2013, 1:28:11 PM9/8/13
to networking
2013/9/8 Jens Maurer <Jens....@gmx.net>

When I configure an interface, I can't see why I would use
operator++ absent some special-case hackery as in your case.

BTW, some years ago Scott Meyers talked about keyholes and I hope that the standard
does not introduce unecessary keyholes.
At least the standard should prevent code from inexperienced developers which tried to
cast the ip-address from the string-representation (ignoring that it was a textual representation)
and increment it by one (resulting in such things like 172.16.1.256).

Jens Maurer

unread,
Sep 8, 2013, 3:57:05 PM9/8/13
to netwo...@isocpp.org
On 09/08/2013 07:28 PM, Oliver Kowalke wrote:
> At least the standard should prevent code from inexperienced developers which tried to
> cast the ip-address from the string-representation (ignoring that it was a textual representation)
> and increment it by one (resulting in such things like 172.16.1.256).

The standard does not prevent code from inexperienced developers
that iterate beyond the end of a std::vector, either.

Your example (textual conversion, then half-way parsing, then increment,
then probably textual conversion back to ip::address_vX)
sounds a lot like shooting yourself in the foot on purpose, something
that C/C++ has never attempted to prevent.

Jens

Oliver Kowalke

unread,
Sep 8, 2013, 4:04:10 PM9/8/13
to networking
2013/9/8 Jens Maurer <Jens....@gmx.net>

The standard does not prevent code from inexperienced developers
that iterate beyond the end of a std::vector, either.

Your example (textual conversion, then half-way parsing, then increment,
then probably textual conversion back to ip::address_vX)
sounds a lot like shooting yourself in the foot on purpose, something
that C/C++ has never attempted to prevent.

why is it such a problem to add a small function doing the job? it would prevent
developers for mistakes - keep the interface small and make it hard to misuse.

Frank Birbacher

unread,
Sep 8, 2013, 4:45:19 PM9/8/13
to netwo...@isocpp.org
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi!

Am 08.09.2013 um 22:04 schrieb Oliver Kowalke:
> why is it such a problem to add a small function doing the job? it would prevent
> developers for mistakes - keep the interface small and make it hard to misuse.

The operator ++ for ip addresses won't fit all needs. On one hand it should be a low level operation that just increments the bit representation of the address (=small function). On the other hand one might expect that it skips the broadcast (.255) and network (.0) addresses or has some more knowledge about what the addresses mean (=hard to misuse). In the first case: whatever code “requires” the operator ++ ties itself to a solution instead of relying on an address range interface (dependency inversion principle). In the latter case the logic is too heavy for the address class.

Not every “solution” that can be made to accomplish a task should make it into the standard. In my opinion the operator ++ is not clearly defined as a general yet simple function. The proposed low-level increment is useless without further logic and feels like a loaded gun given to you. I'd rather accept an address range class that allows traversal of the range.

Frank
-----BEGIN PGP SIGNATURE-----
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
Comment: GPGTools - http://gpgtools.org
Comment: keyserver x-hkp://pool.sks-keyservers.net

iEYEARECAAYFAlIs4d8ACgkQhAOUmAZhnmps8gCfakofAi7T7gg9ZHb6dHWj814C
nvIAn2Di/8coB39+1NPJul/n5mMcxyHL
=hBcP
-----END PGP SIGNATURE-----

Oliver Kowalke

unread,
Sep 9, 2013, 2:36:40 AM9/9/13
to netwo...@isocpp.org, frank.b...@rwth-aachen.de
Am Sonntag, 8. September 2013 22:45:19 UTC+2 schrieb Frank Birbacher:
The operator ++ for ip addresses won't fit all needs. On one hand it should be a low level operation that just increments the bit representation of the address (=small function). On the other hand one might expect that it skips the broadcast (.255) and network (.0) addresses or has some more knowledge about what the addresses mean (=hard to misuse). In the first case: whatever code “requires” the operator ++ ties itself to a solution instead of relying on an address range interface (dependency inversion principle). In the latter case the logic is too heavy for the address class.

Not every “solution” that can be made to accomplish a task should make it into the standard. In my opinion the operator ++ is not clearly defined as a general yet simple function. The proposed low-level increment is useless without further logic and feels like a loaded gun given to you. I'd rather accept an address range class that allows traversal of the range.

I think the argumentation is not correct.

1.) argument that increment could be done via to_bytes() member-fn, e.g. the interface should be small and functions which can be implemented
using to_bytes()/to_ulong() should not be part of the interface:
-> this design rule is already violated because is_multicast(), is_unspecified()... are part of the public interface and simple bit-operations on the u_long/bytes representation.
-> to be consistent to the design rule those member-fn must be removed or this argument is not valid for an increment-op

2.) because you did not encounter such an requirement like get the predecessor / successor of an ip-address or to iterate through a range of ip-address in your daily-work does not
mean it is negligibly small. many network applications are written in C++ (and hopefully many more in the future) - the developers will be faced at such requirements as described.
unfortunately very view C++ developers join the C++ standardization forums like this one, e.g. you experience might not be representative.

3.) focusing the design of ip-address classes only for the purpose of using it together with sockets (== pure network I/O) introduces an unnecessary keyhole problem.

4.) ' the operator ++ is not clearly defined as a general' - in my opinion operator++() == generate the successor address, operator--() == generate the predecessor address.

5.) 'might expect that it skips the broadcast (.255) and network (.0) addresses or has some more knowledge about what the addresses' : broadcast- and any-address are vaild ip-addresses
and should not be skipped. if you needd to detect such 'special' address the interface already provides test-functions like is_multicast(), is_loopback(), any(), broadcast(), ...

Christopher Kohlhoff

unread,
Sep 9, 2013, 3:03:10 AM9/9/13
to netwo...@isocpp.org
Hi,

On Mon, Sep 9, 2013, at 04:36 PM, Oliver Kowalke wrote:

> 1.) argument that increment could be done via to_bytes() member-fn, e.g.
> the interface should be small and functions which can be implemented
> using to_bytes()/to_ulong() should not be part of the interface:
> -> this design rule is already violated because is_multicast(),
> is_unspecified()... are part of the public interface and simple
> bit-operations on the u_long/bytes representation.
> -> to be consistent to the design rule those member-fn must be removed or
> this argument is not valid for an increment-op

It isn't quite the same is is_multicast() and friends do add additional
value, in that they "know" which bits to test to determine if the
address is a multicast address, etc.

> 2.) because you did not encounter such an requirement like get the
> predecessor / successor of an ip-address or to iterate through a range of
> ip-address in your daily-work does not
> mean it is negligibly small. many network applications are written in C++
> (and hopefully many more in the future) - the developers will be faced at
> such requirements as described.
> unfortunately very view C++ developers join the C++ standardization
> forums
> like this one, e.g. you experience might not be representative.
>
> 3.) focusing the design of ip-address classes only for the purpose of
> using
> it together with sockets (== pure network I/O) introduces an unnecessary
> keyhole problem.

My background is certainly focused on network I/O so there may be use
cases not well covered.

I have no particular position (yet) on whether this is a good addition,
except to say that I don't think operator++/-- are good names for it.
From memory, one of the suggestions from Bristol was that operator< be
replaced with a specialisation of std::less, which I presume was on the
basis of making the classes look *less* like arithmetic types. Perhaps
the names next/prev or a separate address range enumerator would be more
appropriate?

In any case, feel free to fork this and experiment with proposed
changes:

https://github.com/chriskohlhoff/ip-address

Cheers,
Chris

Oliver Kowalke

unread,
Sep 9, 2013, 3:18:42 AM9/9/13
to networking
2013/9/9 Christopher Kohlhoff <chris_k...@fastmail.fm>

It isn't quite the same is is_multicast() and friends do add additional
value, in that they "know" which bits to test to determine if the
address is a multicast address, etc.

hmm - I don't get it. the functions generating the predecessor/successor
do also 'know' which bit must be set.
I agree that both functions alter the internal representation instead of only testing it.
A solution could be to rename operator++/operator-- with predecessor()/successor() (as you suggested)
and let both return a new ip::address_v4/6.
 
I have no particular position (yet) on whether this is a good addition,
except to say that I don't think operator++/-- are good names for it.
From memory, one of the suggestions from Bristol was that operator< be
replaced with a specialisation of std::less, which I presume was on the
basis of making the classes look *less* like arithmetic types. Perhaps
the names next/prev or a separate address range enumerator would be more
appropriate?

I agree - I do not stick on operator++/operator-- - I need only some functionality to
step through the ip-address range.

address_v4 address_v4::predecessor();
address_v4 address_v4::successor();

 
In any case, feel free to fork this and experiment with proposed
changes:

https://github.com/chriskohlhoff/ip-address

the company I'm working for produces a lot of network-centric systems (family of) and boost.asio
is used a lot for network I/O. But the applications require much more so that we can shortly to the
conclusion that the address classes of boost.asio (as the proposal is based on) do not fit in all cases.
We were forced to create the same classes with additional features - determine the predecessor/successor
is one of those.
My intention is to prevent that other developers have to 'specialized' the standard address classes in this case.

Christopher Kohlhoff

unread,
Sep 9, 2013, 3:59:31 AM9/9/13
to netwo...@isocpp.org


On Mon, Sep 9, 2013, at 05:18 PM, Oliver Kowalke wrote:
> 2013/9/9 Christopher Kohlhoff <chris_k...@fastmail.fm>
>
> > It isn't quite the same is is_multicast() and friends do add additional
> > value, in that they "know" which bits to test to determine if the
> > address is a multicast address, etc.
> >
>
> hmm - I don't get it. the functions generating the predecessor/successor
> do also 'know' which bit must be set.

I simply mean that the "+1" in "to_ulong() + 1" doesn't look much like a
special value when compared with "(to_ulong() & 0xF0000000) ==
0xE0000000" :)

> the company I'm working for produces a lot of network-centric systems
> (family of) and boost.asio
> is used a lot for network I/O. But the applications require much more so
> that we can shortly to the
> conclusion that the address classes of boost.asio (as the proposal is
> based
> on) do not fit in all cases.
> We were forced to create the same classes with additional features -
> determine the predecessor/successor
> is one of those.
> My intention is to prevent that other developers have to 'specialized'
> the
> standard address classes in this case.

Hmm, everything should be functionally possible using free functions on
top of the existing address classes (but probably not always in the most
efficient way). If you have time, I suggest forking the ip-address
github
repository so we can see what the changes are. I wouldn't necessarily
say we should include everything including the kitchen sink, but ideally
the classes should allow some extensibility via free functions and not
require a re-implementation.

Cheers,
Chris

Oliver Kowalke

unread,
Sep 9, 2013, 5:19:43 AM9/9/13
to netwo...@isocpp.org, chris_k...@fastmail.fm
Am Montag, 9. September 2013 09:03:10 UTC+2 schrieb Christopher Kohlhoff:
In any case, feel free to fork this and experiment with proposed
changes:

https://github.com/chriskohlhoff/ip-address

forked to https://github.com/olk/ip-address - contains a quick-and-dirty hack for address_v4 and address_v6.
needs more test-cases (especially for address_v6).

Felipe Magno de Almeida

unread,
Sep 10, 2013, 4:34:01 PM9/10/13
to netwo...@isocpp.org, frank.b...@rwth-aachen.de
On Mon, Sep 9, 2013 at 3:36 AM, Oliver Kowalke <oliver....@gmail.com> wrote:
> Am Sonntag, 8. September 2013 22:45:19 UTC+2 schrieb Frank Birbacher:

[snip]

> 4.) ' the operator ++ is not clearly defined as a general' - in my opinion
> operator++() == generate the successor address, operator--() == generate the
> predecessor address.

It seems quite obvious to me the semantics of operator++ and operator-- if
we already have a operator<. Given ip::address a, b and c.

b = a;
++b;
\forall c in ip::address: a < c ==> b < c or b == c.


Regards,
--
Felipe Magno de Almeida

Nevin Liber

unread,
Sep 10, 2013, 4:40:39 PM9/10/13
to netwo...@isocpp.org
On 10 September 2013 15:34, Felipe Magno de Almeida <felipe.m...@gmail.com> wrote:
On Mon, Sep 9, 2013 at 3:36 AM, Oliver Kowalke <oliver....@gmail.com> wrote:
> Am Sonntag, 8. September 2013 22:45:19 UTC+2 schrieb Frank Birbacher:

[snip]

> 4.) ' the operator ++ is not clearly defined as a general' - in my opinion
> operator++() == generate the successor address, operator--() == generate the
> predecessor address.

It seems quite obvious to me the semantics of operator++ and operator-- if
we already have a operator<.

Is it?  Does operator< produce the same ordering on big endian and little endian machines?

Just asking...
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

Oliver Kowalke

unread,
Sep 10, 2013, 5:18:29 PM9/10/13
to networking
2013/9/10 Nevin Liber <ne...@eviloverlord.com>
Incrementing IP addresses is weird at the corner cases (crossing class boundaries, for instance). 

could you explain it in more detail please?
 
While there certainly is a natural ordering for certain subsets, I don't know that there is a natural total ordering over all IP addresses.

IPv4 is a 32bit field and IPv6 is a 128bit field - why is it not totally ordered?

Nevin Liber

unread,
Sep 10, 2013, 5:37:55 PM9/10/13
to networking
On 10 September 2013 16:18, Oliver Kowalke <oliver....@gmail.com> wrote:
2013/9/10 Nevin Liber <ne...@eviloverlord.com>
Incrementing IP addresses is weird at the corner cases (crossing class boundaries, for instance). 

could you explain it in more detail please?

Why would I ever want to increment from, say 126.255.255.255 to 127.0.0.0?  Why would anyone ever want to increment to loopback?
 
While there certainly is a natural ordering for certain subsets, I don't know that there is a natural total ordering over all IP addresses.

IPv4 is a 32bit field and IPv6 is a 128bit field - why is it not totally ordered?

I'm not saying IP addresses cannot be totally ordered; they certainly can be (and already are in the proposal).  That is a different question than specifying what that ordering is.  But what makes an order "natural"?  Why not, for instance, make loopback addresses less than all other addresses?

Like I said, this is not my call; I just want people aware of the issue (if there is one).

Felipe Magno de Almeida

unread,
Sep 10, 2013, 4:45:31 PM9/10/13
to netwo...@isocpp.org
On Tue, Sep 10, 2013 at 5:40 PM, Nevin Liber <ne...@eviloverlord.com> wrote:
> On 10 September 2013 15:34, Felipe Magno de Almeida

[snip]

>> It seems quite obvious to me the semantics of operator++ and operator-- if
>> we already have a operator<.
>
>
> Is it? Does operator< produce the same ordering on big endian and little
> endian machines?
>
> Just asking...

I don't know. But if operator< is broken, then it should be fixed. But
doing anything
else for operator++ is just crazy IMO.

> --
> Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404


Felipe Magno de Almeida

unread,
Sep 10, 2013, 4:55:47 PM9/10/13
to netwo...@isocpp.org
On Tue, Sep 10, 2013 at 5:50 PM, Nevin Liber <ne...@eviloverlord.com> wrote:
> On 10 September 2013 15:45, Felipe Magno de Almeida
> <felipe.m...@gmail.com> wrote:
>>
>> > Is it? Does operator< produce the same ordering on big endian and
>> > little
>> > endian machines?
>> >
>> > Just asking...
>>
>> I don't know. But if operator< is broken, then it should be fixed.
>
>
> IMO, that would not make operator< broken. All that is needed is a strict
> weak ordering for use as a key in a set/map, and you would want the natural
> ordering so as not to incur a performance penalty (by either doing a byte by
> byte comparison or forcing an endian swap on some architectures).

You do not find this property important to an object: b = a, a < ++b ?

A strict weak ordering for use as a key in a set/map is given by std::less,
operator< should always be about natural ordering, not performance, IMO.

> --
> Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404

Regards,

Nevin Liber

unread,
Sep 10, 2013, 5:09:14 PM9/10/13
to netwo...@isocpp.org
On 10 September 2013 15:55, Felipe Magno de Almeida <felipe.m...@gmail.com> wrote:
On Tue, Sep 10, 2013 at 5:50 PM, Nevin Liber <ne...@eviloverlord.com> wrote:
> On 10 September 2013 15:45, Felipe Magno de Almeida
> <felipe.m...@gmail.com> wrote:
>>
>> > Is it?  Does operator< produce the same ordering on big endian and
>> > little
>> > endian machines?
>> >
>> > Just asking...
>>
>> I don't know. But if operator< is broken, then it should be fixed.
>
>
> IMO, that would not make operator< broken.  All that is needed is a strict
> weak ordering for use as a key in a set/map, and you would want the natural
> ordering so as not to incur a performance penalty (by either doing a byte by
> byte comparison or forcing an endian swap on some architectures).

You do not find this property important to an object: b = a, a < ++b ?

Incrementing IP addresses is weird at the corner cases (crossing class boundaries, for instance).   While there certainly is a natural ordering for certain subsets, I don't know that there is a natural total ordering over all IP addresses.  Anyway, it's not my call; I'm just bringing up the issue.
 
A strict weak ordering for use as a key in a set/map is given by std::less,
operator< should always be about natural ordering, not performance, IMO.

I've already made my opinion on this quite clear on std-discussion; basically, std::less should always call down to operator<, and the only specialization allowed is for pointers because the language says they may not be totally ordered.  If you wish to discuss the issue in general, that is probably a better place.

I'm guessing we'll be spending a fair bit of committee time discussing relation operators.

Regards,
--

Nevin Liber

unread,
Sep 10, 2013, 4:50:48 PM9/10/13
to networking
On 10 September 2013 15:45, Felipe Magno de Almeida <felipe.m...@gmail.com> wrote:

> Is it?  Does operator< produce the same ordering on big endian and little
> endian machines?
>
> Just asking...

I don't know. But if operator< is broken, then it should be fixed.

IMO, that would not make operator< broken.  All that is needed is a strict weak ordering for use as a key in a set/map, and you would want the natural ordering so as not to incur a performance penalty (by either doing a byte by byte comparison or forcing an endian swap on some architectures).

Oliver Kowalke

unread,
Sep 11, 2013, 2:39:50 AM9/11/13
to networking
2013/9/10 Nevin Liber <ne...@eviloverlord.com>

Why would I ever want to increment from, say 126.255.255.255 to 127.0.0.0?  Why would anyone ever want to increment to loopback?

I would change the wording from increment to successor (-> address_v4 address_v4::successor() and address_v6 address_v6::successor() ...).
126.255.255.255 and 127.0.0.0 are valid ip-addresses but the 'network rules' (like: 'broadcast addresses should not be forwarded') give some addresses special meanings.
IMHO this is another layer of abstraction. ip addresses for itself are equivalent in the sense that those addresses are a sequence of numbers.
BTW, sometimes (under special circumstances) it makes sense to forward subnet-directed broadcast addresses.
 
That is a different question than specifying what that ordering is.

convention - maybe (as one suggestion - network byte order)

Jens Maurer

unread,
Sep 12, 2013, 5:48:07 PM9/12/13
to netwo...@isocpp.org
On 09/11/2013 08:39 AM, Oliver Kowalke wrote:
> 2013/9/10 Nevin Liber <ne...@eviloverlord.com <mailto:ne...@eviloverlord.com>>
>
> Why would I ever want to increment from, say 126.255.255.255 to 127.0.0.0? Why would anyone ever want to increment to loopback?
>
>
> I would change the wording from increment to successor (-> address_v4 address_v4::successor() and address_v6 address_v6::successor() ...).

Notwithstanding my general objection to having an operator++ (or similar) on IP addresses,
that part appears to refer to Nevin's comment.

> 126.255.255.255 and 127.0.0.0 are valid ip-addresses but the 'network rules' (like: 'broadcast addresses should not be forwarded') give some addresses special meanings.
> IMHO this is another layer of abstraction. ip addresses for itself are equivalent in the sense that those addresses are a sequence of numbers.
> BTW, sometimes (under special circumstances) it makes sense to forward subnet-directed broadcast addresses.

This last sentence I don't understand in the context of operator++ for IP addresses.

Jens
Reply all
Reply to author
Forward
0 new messages