Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-07

FPC and IPv6, and BSD

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mark Morgan Lloyd

I'm trying to write a simple finger daemon, capable of both IP4 and IP6. At present it's using an unprivileged socket so as to avoid problems on unix platforms.

I appear to be having problems at the bind() call for IP6 (returns -1), which I suspect is down to my incomplete understanding of the new sockaddr_in6 structure. Has anybody done this successfully?

As a subsidiary question: noting that a client has to be aware of this:

   sockaddr_in6 = packed Record
     {$ifdef SOCK_HAS_SINLEN}  // as per RFC 2553
       sin6_len    : cuint8;
     {$endif}
     sin6_family   : sa_family_t;
..

so that it initialises the sin6_len field if present (some BSD variants?), does it see that conditional automatically if defined? Otherwise how best to do it?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Mark Morgan Lloyd
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 7 lines
I'm trying to write a simple finger daemon, capable of both IP4 and IP6. At present it's using an unprivileged socket so as to avoid problems on unix platforms. I appear to be having problems at the bind() call for IP6 (returns -1), which I suspect is down to my incomplete understanding of the new sockaddr_in6 structure. Has anybody done this successfully?

On Linux >= 2.4.21 attempting to bind a v6 socket also binds the corresponding v4. Appears to need

   bindrc := 1;
   fpsetsockopt(socket6, IPPROTO_IPV6, IPV6_V6ONLY, @bindrc,
SizeOf(bindRc));

to get them to work individually.

Show quoted text 12 lines
As a subsidiary question: noting that a client has to be aware of this: sockaddr_in6 = packed Record {$ifdef SOCK_HAS_SINLEN} // as per RFC 2553 sin6_len : cuint8; {$endif} sin6_family : sa_family_t; .. so that it initialises the sin6_len field if present (some BSD variants?), does it see that conditional automatically if defined? Otherwise how best to do it?

Anybody?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

ZAN DoYe
to Mark Morgan Lloyd: I'm trying to write a simple finger daemon, capable of both IP4 and IP6. At present it's…
Mark Morgan Lloyd wrote
I'm trying to write a simple finger daemon, capable of both IP4 and IP6. At present it's using an unprivileged socket so as to avoid problems on unix platforms. I appear to be having problems at the bind() call for IP6 (returns -1), which I suspect is down to my incomplete understanding of the new sockaddr_in6 structure. Has anybody done this successfully?

If you called fpBind, then check fpGetErrno to see what happened. If you do called the bind function in libc. uses initc unit, and check the cerrno.

Show quoted text 11 lines
As a subsidiary question: noting that a client has to be aware of this: sockaddr_in6 = packed Record {$ifdef SOCK_HAS_SINLEN} // as per RFC 2553 sin6_len : cuint8; {$endif} sin6_family : sa_family_t; .. so that it initialises the sin6_len field if present (some BSD variants?), does it see that conditional automatically if defined? Otherwise how best to do it?

You don't worry about the sin6_len field.
`Even if the length field is present, we need never set it and need never examine it, unless we are dealing with routing sockets. It is used within the kernel by the routines that deal with socket address structures from various protocol families.' --- UNP v1

And you don't even need to be aware of sockaddr_in6 or sockaddr_in
as in a net lib:
     function tTcpIpServer.listen(address, service: ansiString; backlog: cint): boolean;
         var
             hint: tAddrinfo;
             addrinfo: paddrinfo;
             encounterError: boolean= true;
     begin
         result:= false;
         fillByte(hint, sizeof(hint), 0);
         hint.ai_socktype:= SOCK_STREAM;
         if getaddrinfo(pchar(address), pchar(service), @hint, @addrinfo) = 0 then begin
             if addrinfo  nil then begin
                 handle:= fpSocket(addrinfo^.ai_family, SOCK_STREAM, 0);
                 if fpBind(handle, addrinfo^.ai_addr, addrinfo^.ai_addrlen) = 0 then
                     encounterError:= false; // how lucky we are :)
             end;
         end;
         freeaddrinfo(addrinfo);
         if not encounterError then
             if fpListen(handle, backlog) = 0 then
                 result:= true;
     end;

We can invoke aTcpIpServer.listen('::0', '12345', 16) or aTcpIpServer.listen('0', '12345', 16), listen for incoming ip6/ip4 connections. getaddrinfo is handy.

Reply by email

Mark Morgan Lloyd
to ZAN DoYe
ZAN DoYe wrote 11 lines
On 2012-07-23 21:51, Mark Morgan Lloyd wrote: > I'm trying to write a simple finger daemon, capable of both IP4 and > IP6. At present it's using an unprivileged socket so as to avoid > problems on unix platforms. > > I appear to be having problems at the bind() call for IP6 (returns > -1), which I suspect is down to my incomplete understanding of the new > sockaddr_in6 structure. Has anybody done this successfully? > If you called fpBind, then check fpGetErrno to see what happened. If you do called the bind function in libc. uses initc unit, and check the cerrno.

Thanks, the problem was entirely down to IP6 also binding IP4. I've coded to leave this as an option.

Show quoted text 18 lines
> As a subsidiary question: noting that a client has to be aware of this: > > sockaddr_in6 = packed Record > {$ifdef SOCK_HAS_SINLEN} // as per RFC 2553 > sin6_len : cuint8; > {$endif} > sin6_family : sa_family_t; > .. > > so that it initialises the sin6_len field if present (some BSD > variants?), does it see that conditional automatically if defined? > Otherwise how best to do it? > You don't worry about the sin6_len field. `Even if the length field is present, we need never set it and need never examine it, unless we are dealing with routing sockets. It is used within the kernel by the routines that deal with socket address structures from various protocol families.' --- UNP v1

Thanks very much for that, noted.

Remainder noted for reference.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email