From 9a44a542cab11c03215fe3c844dde2529a87258d Mon Sep 17 00:00:00 2001 From: plugwash Date: Fri, 12 Feb 2010 22:16:05 +0000 Subject: [PATCH] freebsd fixups git-svn-id: file:///svnroot/lcore/trunk@75 b1de8a11-f9be-4011-bde0-cc7ace90066a --- binipstuff.pas | 28 ++++++++++++++++++++---- lcoretest.dpr | 1 + lsocket.pas | 59 ++++++++++++++++++++++++++++++++++++++++---------- unixstuff.inc | 8 +++++++ 4 files changed, 81 insertions(+), 15 deletions(-) diff --git a/binipstuff.pas b/binipstuff.pas index 675b03e..8f28a27 100644 --- a/binipstuff.pas +++ b/binipstuff.pas @@ -9,10 +9,8 @@ interface {$include lcoreconfig.inc} {$ifndef win32} -{$ifdef ipv6} uses sockets; {$endif} -{$endif} {$ifdef fpc} {$mode delphi} @@ -24,11 +22,15 @@ uses sockets; const hexchars:array[0..15] of char='0123456789abcdef'; - AF_INET=2; {$ifdef win32} + AF_INET=2; AF_INET6=23; {$else} - AF_INET6=10; + //redeclare these constants so units that use us can use them + //without using sockets directly + AF_INET=AF_INET; + AF_INET6=AF_INET6; + //AF_INET6=10; {$endif} type @@ -155,6 +157,7 @@ function longip(s:string):longint; function needconverttov4(const ip:tbinip):boolean; procedure converttov4(var ip:tbinip); +procedure converttov6(var ip:tbinip); function inaddrvtobinip(inaddrv:tinetsockaddrv):tbinip; function makeinaddrv(addr:tbinip;port:string;var inaddr:tinetsockaddrv):integer; @@ -535,6 +538,23 @@ begin {$endif} end; + +{converts a binary IP to v6 if it is a v4 IP} +procedure converttov6(var ip:tbinip); +begin + {$ifdef ipv6} + if ip.family = AF_INET then begin + ip.family := AF_INET6; + ip.ip6.s6_addr32[3] := ip.ip; + ip.ip6.u6_addr32[0] := 0; + ip.ip6.u6_addr32[1] := 0; + ip.ip6.u6_addr16[4] := 0; + ip.ip6.u6_addr16[5] := $ffff; + end; + {$endif} +end; + + {-----------biniplist stuff--------------------------------------------------} const diff --git a/lcoretest.dpr b/lcoretest.dpr index da31cd6..8be5bea 100755 --- a/lcoretest.dpr +++ b/lcoretest.dpr @@ -192,6 +192,7 @@ begin listensocket.onsessionavailable := sc.sessionavailable; writeln('listening'); listensocket.listen; + writeln('listen call returned'); writeln(listensocket.getxport); writeln('listen socket is number ', listensocket.fdhandlein); writeln('creating and setting up server socket'); diff --git a/lsocket.pas b/lsocket.pas index c099cf5..53205e6 100755 --- a/lsocket.pas +++ b/lsocket.pas @@ -132,6 +132,7 @@ type //this one has to be kept public for now because lcorewsaasyncselect calls it procedure connectionfailedhandler(error:word); private + isv6socket : boolean; //identifies if the socket is v6, set by bindsocket procedure taskcallconnectionfailedhandler(wparam,lparam : longint); procedure connecttimeouthandler(sender:tobject); @@ -351,7 +352,7 @@ begin end; //gethostbyname(localaddr,host); inaddrtempsize := makeinaddrv(forwardlookup(localaddr,0),localport,inaddrtemp); - + isv6socket := (inaddrtemp.inaddr.family = AF_INET6); If Bind(fdhandlein,inaddrtempx,inaddrtempsize)<> {$ifdef win32}0{$else}true{$endif} Then begin state := wsclosed; lasterror := {$ifdef win32}getlasterror{$else}socketerror{$endif}; @@ -384,7 +385,9 @@ begin if addr = '' then begin {$ifdef ipv6} + //writeln('ipv6 is defined'); if not v4listendefault then begin + //writeln('setting addr to ::'); addr := '::'; end else {$endif} @@ -392,11 +395,19 @@ begin end; if isbiniplist(addr) then biniptemp := biniplist_get(addr,0) else biniptemp := forwardlookup(addr,10); addr := ipbintostr(biniptemp); + //writeln('after ipbintostr call addr =',addr); + //writeln('biniptemp.family =',biniptemp.family); + //writeln('AF_INET6=',AF_INET6); + //writeln('PF_INET6=',PF_INET6); + //writeln('AF_INET=',AF_INET); + //writeln('PF_INET=',PF_INET); + fdhandlein := socket(biniptemp.family,socktype,0); {$ifdef ipv6} if (addr = '::') and (origaddr = '') and (fdhandlein < 0) then begin + writeln('failed to create an IPV6 socket with error ',socketerror,'. trying to create an IPV4 one instead'); addr := '0.0.0.0'; - fdhandlein := socket(AF_INET,socktype,0); + fdhandlein := socket(PF_INET,socktype,0); end; {$endif} @@ -411,10 +422,18 @@ begin no := 0; {$ifndef win32} if SetSocketOptions(fdhandlein, SOL_SOCKET, SO_REUSEADDR,yes,sizeof(yes))=-1 then begin - raise ESocketException.create('unable to set socket options'); + raise ESocketException.create('unable to set SO_REUSEADDR socket option'); end; - if SetSocketOptions(fdhandlein, IPPROTO_IPV6,IPV6_V6ONLY,no,sizeof(no))=-1 then begin - raise ESocketException.create('unable to set socket options'); + //writeln('addr=',addr); + //writeln('setting IPV6_V6ONLY option to 0'); + //allow v4 connections on v6 sockets + if biniptemp.family = af_inet6 then begin + if SetSocketOptions(fdhandlein, IPPROTO_IPV6,IPV6_V6ONLY,no,sizeof(no))=-1 then begin + writeln(IPPROTO_IPV6); + writeln(IPV6_V6ONLY); + raise ESocketException.create('unable to set IPV6_V6ONLY socket option error='+inttostr(socketerror)); + + end; end; {$endif} localaddr := addr; @@ -531,15 +550,33 @@ end; function tlsocket.sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer; var - destx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute dest; + {$ifdef ipv6} + realdest : tinetsockaddrv; + biniptemp : tbinip; + {$endif} + destx : {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}; + begin {$ifdef secondlistener} - if assigned(secondlistener) then if (dest.inaddr.family = AF_INET) then begin - result := secondlistener.sendto(dest,destlen,data,len); - exit; - end; + if assigned(secondlistener) then if (dest.inaddr.family = AF_INET) then begin + result := secondlistener.sendto(dest,destlen,data,len); + exit; + end; {$endif} - result := {$ifdef win32}winsock.sendto{$else}system_sendto{$endif}(self.fdhandleout,data^,len,0,destx,destlen); + {$ifdef ipv6} + if isv6socket then begin + biniptemp := inaddrvtobinip(dest); + converttov6(biniptemp); + destlen := makeinaddrv(biniptemp,inttostr(ntohs(dest.InAddr.port)),realdest); + destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@realdest) + end else begin + destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@dest) + end; + {$else} + destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@dest) + {$endif} + + result := {$ifdef win32}winsock.sendto{$else}system_sendto{$endif}(self.fdhandleout,data^,len,0,destx^,destlen); end; diff --git a/unixstuff.inc b/unixstuff.inc index 773656d..b522c74 100755 --- a/unixstuff.inc +++ b/unixstuff.inc @@ -159,5 +159,13 @@ IPV6_V6ONLY = 26; {$endif} {$endif} + {$ifdef freebsd} + //freepascal doesn't seem to define IPV6_V6ONLY on freebsd, the definition + //here is taken from the include files of a freebsd 8 system + const + IPV6_V6ONLY = 27; + {$endif} + {$endif} + \ No newline at end of file -- 2.30.2