[fpc-pascal] FPC and IPv6, and BSD

ZAN DoYe 1123monkey at gmail.com
Fri Jul 27 02:45:27 CEST 2012


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.

> 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.



More information about the fpc-pascal mailing list