X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/f8e139db970666e906db30417763f81e2ae5e801..9a44a542cab11c03215fe3c844dde2529a87258d:/lsocket.pas?ds=inline 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;