www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - looking for testers: std.socket / IPv6

reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Attached is the IPv6 enabled std.socket module and a tiny test programm.
(only tested on Linux but should work on Windows too)

Changes from DMD-0.144's std.socket:
* InternetHost and InternetAddress now support IPv4 and IPv6
* "potected sockaddr_in InternetAddress.sin" has been replaced
by "potected sockaddr_in* InternetAddress.ip4"
* several new constructors in InternetAddress
* InternetAddress[] can now be sorted properly
* "public uint32_t[] InternetHost.addrList" has been replaced
by "public InternetAddress InternetHost.addrList"
* various minor changes to account for IPv6

Todo:
* documentation ...
* testing / unittests

Linux users need to fix std.c.linux.socket.addrinfo.
The proper struct is:

# struct addrinfo
# {
#    int32_t ai_flags; 
#    int32_t ai_family;
#    int32_t ai_socktype;
#    int32_t ai_protocol;
#    size_t ai_addrlen;
#    sockaddr* ai_addr;
#    char* ai_canonname;
#    addrinfo* ai_next;
# }

sample output of the test.d:

# server's address: [::1]:65190
#
# -- Client View --
# local: [::1]:38405
# remote: [::1]:65190
#
# received: 60 bytes
# BEGIN >>
# -- Server View --
# local: [::1]:65190
# remote: [::1]:38405
# << END

Thomas
Jan 28 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This is the second version of the IPv6 enabled std.socket module.

Changes since the first post:
* improved handling of unhandled AddressFamilies
* added unittests / invariant
* marked IPv4 only functions with "/// $(D_COMMENT IPv4 only)"
* fixed "InternetAddress.this(sockaddr_in6*)"

(please check digitalmars.D.bugs before testing the attachement)

Thomas
Jan 29 2006
parent reply "Chris Miller" <chris dprogramming.com> writes:
On Sun, 29 Jan 2006 11:54:30 -0500, Thomas Kuehne <thomas-dloop kuehne.cn>  
wrote:
 This is the second version of the IPv6 enabled std.socket module.

I'm not sure it's a good idea to have InternetAddress support IPv4 and IPv6. My original plan was to have a separate Address for IPv6 (possibly named Internet6Address). I'm more unsure about InternetHost. Also, there's a somewhat vague naming convention used in std.socket: address refers to an Address or derived (class), and addr refers to the actual value of it (uint for IPv4). I noticed your version doesn't adhere to this.
Jan 29 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chris Miller schrieb am 2006-01-29:
 On Sun, 29 Jan 2006 11:54:30 -0500, Thomas Kuehne <thomas-dloop kuehne.cn>  
 wrote:
 This is the second version of the IPv6 enabled std.socket module.

I'm not sure it's a good idea to have InternetAddress support IPv4 and IPv6. My original plan was to have a separate Address for IPv6 (possibly named Internet6Address). I'm more unsure about InternetHost.

Neither is IPv4 a subset of IPv6 nor is IPv6 a subset of IPv4. While it is possible to represent IPv4 with mapped IPv6 (255.1.16.3 <-> ::FFFF:FF01:1003), it is impossible to use IPv6 sockets for IPv4. Thus the follwing designs aren't usefull: 1) abstract class Address; class InternetAddress4 : Address; class InternetAddress6 : InternetAddress4; 2) abstract class Address; class InternetAddress6 : Address; class InternetAddress4 : InternetAddress6; One seemingly obvious solution would be: 3) abstract class Address; class InternetAddress : Address; (-> IPv4) class InternetAddress6 : Address; The vast majority of applications have no to reason to discriminate between IPv4 and IPv6 but would have to use quite a bit of code duplication to implement 3). OK, next round: 4) abstract class Address; interface InternetAddress; class InternetAddress4 : Address, InternetAddress; class InternetAddress6 : Address, InternetAddress; The design might seem clean, but changing one of the core types from "class" to "interface" will lead to quite a few bugs. The current design is: 5) abstract class Address; class InternetAddress : Address; (-> IPv4 & IPv6) This keeps the commonly required code changes to a minimum and allows incremental updates to use IPv6. e.g. uint addr() (throws exception if used with IPv6) -> ubyte[] address() A possible extension of the current design: 6) abstract class Address; class InternetAddress : Address; (-> IPv4 & IPv6) class InternetAddress4 : InternetAddress; (-> constructors only return IPv4 addresses) class InternetAddress6 : InternetAddress; (-> constructors only return IPv6 addresses)
 Also, there's a somewhat vague naming convention used in std.socket:  
 address refers to an Address or derived (class), and addr refers to the  
 actual value of it (uint for IPv4). I noticed your version doesn't adhere  
 to this.

I kind of did: uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.address(); // IPv4 & IPv6 The alternatives are: A) ubyte[] InternetAddress.addr(); The clean solution, but would require instant code updates in quite a few applications. B) ucent InternetAddress.addr(); ucent is reserved for 128 bit unsigned ints but not implemented. Would you like C's way and rather use the following? uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.addr2(); // IPv4 & IPv6 Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFD3xhC3w+/yD4P9tIRAh9EAJ0eTQUPOyNcTUTynlVCYnupaCvI+gCeMN94 0HQTywfN9FUNh6VjPG+D9qw= =2CYt -----END PGP SIGNATURE-----
Jan 30 2006
parent reply "Chris Miller" <chris dprogramming.com> writes:
On Tue, 31 Jan 2006 02:38:39 -0500, Thomas Kuehne <thomas-dloop kuehne.cn>  
wrote:

 One seemingly obvious solution would be:
 3)
 abstract class Address;
 class InternetAddress : Address; (-> IPv4)
 class InternetAddress6 : Address;

 The vast majority of applications have no to reason to discriminate  
 between
 IPv4 and IPv6 but would have to use quite a bit of code duplication to
 implement 3).

That was the original plan, but you make a good point.
 OK, next round:
 4)
 abstract class Address;
 interface InternetAddress;
 class InternetAddress4 : Address, InternetAddress;
 class InternetAddress6 : Address, InternetAddress;

 The design might seem clean, but changing one of the core types
 from "class" to "interface" will lead to quite a few bugs.

 The current design is:
 5)
 abstract class Address;
 class InternetAddress : Address; (-> IPv4 & IPv6)

 This keeps the commonly required code changes to a minimum and allows
 incremental updates to use IPv6.
 e.g. uint addr() (throws exception if used with IPv6) -> ubyte[]  
 address()

 A possible extension of the current design:
 6)
 abstract class Address;
 class InternetAddress : Address; (-> IPv4 & IPv6)
 class InternetAddress4 : InternetAddress;
 (-> constructors only return IPv4 addresses)
 class InternetAddress6 : InternetAddress;
 (-> constructors only return IPv6 addresses)

That might be fair.
 Also, there's a somewhat vague naming convention used in std.socket:
 address refers to an Address or derived (class), and addr refers to the
 actual value of it (uint for IPv4). I noticed your version doesn't  
 adhere
 to this.

I kind of did: uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.address(); // IPv4 & IPv6 The alternatives are: A) ubyte[] InternetAddress.addr(); The clean solution, but would require instant code updates in quite a few applications. B) ucent InternetAddress.addr(); ucent is reserved for 128 bit unsigned ints but not implemented. Would you like C's way and rather use the following? uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.addr2(); // IPv4 & IPv6

Not really fond of either, how about: uint addr(); // Current one; throws exception if used with IPv6 ubyte[] getAddr(); // (or getAddrBytes) IPv4 & IPv6 About InternetHost, may wish to leave addrList the way it was and deprecate it, then add addressList for this new stuf.
Feb 02 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Chris Miller schrieb am 2006-02-03:
 A possible extension of the current design:
 6)
 abstract class Address;
 class InternetAddress : Address; (-> IPv4 & IPv6)
 class InternetAddress4 : InternetAddress;
 (-> constructors only return IPv4 addresses)
 class InternetAddress6 : InternetAddress;
 (-> constructors only return IPv6 addresses)

That might be fair.

Implemented with a "semi-abstract" InternetAddress class. "semi-abstract" concept: # class Animal{ # int getValue(){ # assert(0); # } # } # # class Horse : Animal{ # override int getValue(){ # return 2; # } # } # # class Fish : Animal{ # override int getValue(){ # return -97; # } # } This seems to be the best way to keep the implementation simple and extendeable. e.g. "uint InternetAddress.parse(char[])" could be deprecated in the future and only "uint InternetAddress4.parse(char[])" would remain.
 Also, there's a somewhat vague naming convention used in std.socket:
 address refers to an Address or derived (class), and addr refers to the
 actual value of it (uint for IPv4). I noticed your version doesn't  
 adhere
 to this.

I kind of did: uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.address(); // IPv4 & IPv6 The alternatives are: A) ubyte[] InternetAddress.addr(); The clean solution, but would require instant code updates in quite a few applications. B) ucent InternetAddress.addr(); ucent is reserved for 128 bit unsigned ints but not implemented. Would you like C's way and rather use the following? uint InternetAddress.addr(); // throws exception if used with IPv6 ubyte[] InternetAddress.addr2(); // IPv4 & IPv6

Not really fond of either, how about: uint addr(); // Current one; throws exception if used with IPv6 ubyte[] getAddr(); // (or getAddrBytes) IPv4 & IPv6

done
 About InternetHost, may wish to leave addrList the way it was and  
 deprecate it, then add addressList for this new stuf.

How are you goning to ensure that addrList and addressList are synchronized? Thomas
Feb 04 2006
parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

some more code clean up from the previous post

As far as I'm aware, there aren't any bugs left in the code.

Thomas
Feb 04 2006
parent Sohgo Takeuchi <sohgo sohgo.dyndns.org> writes:
Thomas Kuehne Wrote:

 some more code clean up from the previous post
 
 As far as I'm aware, there aren't any bugs left in the code.

I've compiled the std/socket.d of socket_ip6_4.zip on the current D1 and D2 environment. But the compiler outputs a lot of error messages. Do you have a plan to catch up with current D1 and D2? regards,
Mar 20 2010