/[lcore]/trunk/lsocket.pas
ViewVC logotype

Diff of /trunk/lsocket.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2 by beware, Sun Mar 30 00:16:07 2008 UTC revision 75 by plugwash, Fri Feb 12 22:16:05 2010 UTC
# Line 54  Line 54 
54        sockets,        sockets,
55      {$endif}      {$endif}
56      classes,{pgdebugout,}pgtypes,lcore,fd_utils,binipstuff,dnssync;      classes,{pgdebugout,}pgtypes,lcore,fd_utils,binipstuff,dnssync;
57    
58    {$ifdef ipv6}
59    const
60      v4listendefault:boolean=false;
61    {$endif}
62    
63    
64  type  type
65    sunB = packed record    sunB = packed record
66      s_b1, s_b2, s_b3, s_b4: byte;      s_b1, s_b2, s_b3, s_b4: byte;
# Line 92  Line 99 
99        localaddr:string;        localaddr:string;
100        localport:string;        localport:string;
101        proto:string;        proto:string;
102        udp:boolean;        udp,dgram:boolean;
103        listenqueue:integer;        listenqueue:integer;
104        procedure connectionfailedhandler(error:word);        {$ifdef secondlistener}
105        procedure connecttimeouthandler(sender:tobject);        secondlistener:tlsocket;
106        procedure connectsuccesshandler;        lastsessionfromsecond:boolean;
107          procedure secondaccepthandler(sender:tobject;error:word);
108          procedure internalclose(error:word);override;
109          {$endif}
110        function getaddrsize:integer;        function getaddrsize:integer;
111        procedure connect; virtual;        procedure connect; virtual;
112        procedure realconnect;        procedure realconnect;
# Line 105  Line 115 
115        function accept : longint;        function accept : longint;
116        function sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer; virtual;        function sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer; virtual;
117        function receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;var srclen:integer):integer; virtual;        function receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;var srclen:integer):integer; virtual;
118        //procedure internalclose(error:word);override;  
119        procedure handlefdtrigger(readtrigger,writetrigger:boolean); override;        procedure handlefdtrigger(readtrigger,writetrigger:boolean); override;
120        function send(data:pointer;len:integer):integer;override;        function send(data:pointer;len:integer):integer;override;
121        procedure sendstr(const str : string);override;        procedure sendstr(const str : string);override;
# Line 118  Line 128 
128        function getXport:string; virtual;        function getXport:string; virtual;
129        function getpeerport:string; virtual;        function getpeerport:string; virtual;
130        constructor Create(AOwner: TComponent); override;        constructor Create(AOwner: TComponent); override;
131    
132          //this one has to be kept public for now because lcorewsaasyncselect calls it
133          procedure connectionfailedhandler(error:word);
134        private
135          isv6socket : boolean; //identifies if the socket is v6, set by bindsocket
136          procedure taskcallconnectionfailedhandler(wparam,lparam : longint);
137    
138          procedure connecttimeouthandler(sender:tobject);
139          procedure connectsuccesshandler;
140        {$ifdef win32}        {$ifdef win32}
141          procedure myfdclose(fd : integer); override;          procedure myfdclose(fd : integer); override;
142          function myfdwrite(fd: LongInt;const buf;size: LongInt):LongInt; override;          function myfdwrite(fd: LongInt;const buf;size: LongInt):LongInt; override;
# Line 129  Line 148 
148    twsocket=tlsocket; {easy}    twsocket=tlsocket; {easy}
149    
150    
 {!!!function longipdns(s:string):longint;}  
   
 {$ifdef ipv6}  
 const  
   v4listendefault:boolean=false;  
 {$endif}  
   
   
151  const  const
152    TCP_NODELAY=1;    TCP_NODELAY=1;
153    IPPROTO_TCP=6;    IPPROTO_TCP=6;
# Line 150  Line 161 
161    result := inaddrsize(inaddr);    result := inaddrsize(inaddr);
162  end;  end;
163    
164    //I used to use the system versions of these from within lsocket (which has
165    //functions whose name clashes with them) by using sockets.* and but I can't do
166    //that anymore since in some cases connect is now provided by unixstuff.inc
167    //hence these wrapper functions --plugwash
168    {$ifndef win32}
169      function system_Connect(Sock: LongInt;const Addr;Addrlen: LongInt):Boolean;
170      begin
171        result := connect(sock,addr,addrlen);
172      end;
173      function system_SendTo(Sock: LongInt; const Buf;BufLen: LongInt;Flags: LongInt;var Addr;AddrLen: LongInt):LongInt;
174      begin
175        result := sendto(sock,buf,buflen,flags,addr,addrlen);
176      end;
177      function system_getpeername(Sock: LongInt;var Addr;var Addrlen: LongInt):LongInt;
178      begin
179        result := getpeername(sock,addr,addrlen);
180      end;
181      function system_listen(Sock: LongInt; MaxConnect: LongInt):Boolean;
182      begin
183        result := listen(sock,maxconnect);
184      end;
185      function system_Accept(Sock: LongInt;var Addr;var Addrlen: LongInt):LongInt;
186      begin
187        result := accept(sock,addr,addrlen);
188      end;
189    {$endif}
190    
191  procedure tlsocket.realconnect;  procedure tlsocket.realconnect;
192  var  var
193    a:integer;    a,b:integer;
   
194  begin  begin
195  //  writeln('trying to connect to ',ipbintostr(biniplist_get(biniplist,currentip)),'#',port);  //  writeln('trying to connect to ',ipbintostr(biniplist_get(biniplist,currentip)),'#',port);
196    makeinaddrv(biniplist_get(biniplist,currentip),port,inaddr);    makeinaddrv(biniplist_get(biniplist,currentip),port,inaddr);
197    inc(currentip);    inc(currentip);
198    if (currentip >= biniplist_getcount(biniplist)) then trymoreips := false;    if (currentip >= biniplist_getcount(biniplist)) then trymoreips := false;
199    udp := uppercase(proto) = 'UDP';  
200    if udp then a := SOCK_DGRAM else a := SOCK_STREAM;    udp := false;
201    a := Socket(inaddr.inaddr.family,a,0);    if (uppercase(proto) = 'UDP') then begin
202        b := IPPROTO_UDP;
203        a := SOCK_DGRAM;
204        udp := true;
205        dgram := true;
206      end else if (uppercase(proto) = 'TCP') or (uppercase(proto) = '') then begin
207        b := IPPROTO_TCP;
208        a := SOCK_STREAM;
209        dgram := false;
210      end else if (uppercase(proto) = 'ICMP') or (strtointdef(proto,256) < 256) then begin
211        b := strtointdef(proto,IPPROTO_ICMP);
212        a := SOCK_RAW;
213        dgram := true;
214      end else begin
215        raise ESocketException.create('unrecognised protocol');
216      end;
217    
218      a := Socket(inaddr.inaddr.family,a,b);
219    //writeln(ord(inaddr.inaddr.family));    //writeln(ord(inaddr.inaddr.family));
220    if a = -1 then begin    if a = -1 then begin
221      lasterror := {$ifdef win32}getlasterror{$else}socketerror{$endif};      //unable to create socket, fire an error event (better to use an error event
222      raise esocketexception.create('unable to create socket');      //to avoid poor interaction with multilistener stuff.
223        //a socket value of -2 is a special value to say there is no socket but
224        //we want internalclose to act as if there was
225        fdhandlein := -2;
226        fdhandleout := -2;
227        tltask.create(taskcallconnectionfailedhandler,self,{$ifdef win32}wsagetlasterror{$else}socketerror{$endif},0);
228        exit;
229    end;    end;
230    try    try
231      dup(a);      dup(a);
232      bindsocket;      bindsocket;
233      if udp then begin      if dgram then begin
234        {$ifndef win32}        {$ifndef win32}
235          SetSocketOptions(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));          SetSocketOptions(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));
236          {$else}
237            SetSockOpt(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));
238        {$endif}        {$endif}
239        state := wsconnected;        state := wsconnected;
240        if assigned(onsessionconnected) then onsessionconnected(self,0);        if assigned(onsessionconnected) then onsessionconnected(self,0);
# Line 186  Line 247 
247          //writeln(inaddr.inaddr.port);          //writeln(inaddr.inaddr.port);
248          winsock.Connect(fdhandlein,winsock.psockaddr(@inADDR)^,getaddrsize);          winsock.Connect(fdhandlein,winsock.psockaddr(@inADDR)^,getaddrsize);
249        {$else}        {$else}
250          sockets.Connect(fdhandlein,inADDR,getaddrsize);          system_Connect(fdhandlein,inADDR,getaddrsize);
251        {$endif}        {$endif}
252        eventcore.rmasterset(fdhandlein,false);        eventcore.rmasterset(fdhandlein,false);
253        eventcore.wmasterset(fdhandleout);        eventcore.wmasterset(fdhandleout);
# Line 211  Line 272 
272    realconnect;    realconnect;
273  end;  end;
274    
275    
276    
277    
278  procedure tlsocket.connect;  procedure tlsocket.connect;
279  var  var
280    a:integer;    a:integer;
# Line 218  Line 282 
282  begin  begin
283    if state <> wsclosed then close;    if state <> wsclosed then close;
284    //prevtime := 0;    //prevtime := 0;
285      if isbiniplist(addr) then biniplist := addr else biniplist := forwardlookuplist(addr,0);
   biniplist := forwardlookuplist(addr,0);  
286    if biniplist_getcount(biniplist) = 0 then raise exception.create('unable to resolve '+addr);    if biniplist_getcount(biniplist) = 0 then raise exception.create('unable to resolve '+addr);
287    
288    //makeinaddrv(addr,port,inaddr);    //makeinaddrv(addr,port,inaddr);
# Line 227  Line 290 
290    currentip := 0;    currentip := 0;
291    if not assigned(connecttimeout) then begin    if not assigned(connecttimeout) then begin
292      connecttimeout := tltimer.create(self);      connecttimeout := tltimer.create(self);
     connecttimeout.Tag := integer(self);  
293      connecttimeout.ontimer := connecttimeouthandler;      connecttimeout.ontimer := connecttimeouthandler;
294      connecttimeout.interval := 2500;      connecttimeout.interval := 2500;
295      connecttimeout.enabled := false;      connecttimeout.enabled := false;
# Line 237  Line 299 
299    
300  procedure tlsocket.sendstr(const str : string);  procedure tlsocket.sendstr(const str : string);
301  begin  begin
302    if udp then begin    if dgram then begin
303      send(@str[1],length(str))      send(@str[1],length(str))
304    end else begin    end else begin
305      inherited sendstr(str);      inherited sendstr(str);
# Line 246  Line 308 
308    
309  function tlsocket.send(data:pointer;len:integer):integer;  function tlsocket.send(data:pointer;len:integer):integer;
310  begin  begin
311    if udp then begin    if dgram then begin
312  //    writeln('sending to '+ipbintostr(inaddrvtobinip(inaddr)),' ',htons(inaddr.inaddr.port),' ',len,' bytes');  //    writeln('sending to '+ipbintostr(inaddrvtobinip(inaddr)),' ',htons(inaddr.inaddr.port),' ',len,' bytes');
313      result := sendto(inaddr,getaddrsize,data,len);      result := sendto(inaddr,getaddrsize,data,len);
314    
# Line 260  Line 322 
322    
323  function tlsocket.receive(Buf:Pointer;BufSize:integer):integer;  function tlsocket.receive(Buf:Pointer;BufSize:integer):integer;
324  begin  begin
325    if udp then begin    if dgram then begin
326        {$ifdef secondlistener}
327        if lastsessionfromsecond then begin
328          result := secondlistener.receive(buf,bufsize);
329          lastsessionfromsecond := false;
330        end else
331        {$endif}
332      result := myfdread(self.fdhandlein,buf^,bufsize);      result := myfdread(self.fdhandlein,buf^,bufsize);
333    end else begin    end else begin
334      result := inherited receive(buf,bufsize);      result := inherited receive(buf,bufsize);
# Line 283  Line 351 
351          localaddr := '0.0.0.0';          localaddr := '0.0.0.0';
352        end;        end;
353        //gethostbyname(localaddr,host);        //gethostbyname(localaddr,host);
   
354        inaddrtempsize := makeinaddrv(forwardlookup(localaddr,0),localport,inaddrtemp);        inaddrtempsize := makeinaddrv(forwardlookup(localaddr,0),localport,inaddrtemp);
355          isv6socket := (inaddrtemp.inaddr.family = AF_INET6);
356        If Bind(fdhandlein,inaddrtempx,inaddrtempsize)<> {$ifdef win32}0{$else}true{$endif} Then begin        If Bind(fdhandlein,inaddrtempx,inaddrtempsize)<> {$ifdef win32}0{$else}true{$endif} Then begin
357          state := wsclosed;          state := wsclosed;
358          lasterror := {$ifdef win32}getlasterror{$else}socketerror{$endif};          lasterror := {$ifdef win32}getlasterror{$else}socketerror{$endif};
359          raise ESocketException.create('unable to bind, error '+inttostr(lasterror));          raise ESocketException.create('unable to bind on address '+localaddr+'#'+localport+', error '+inttostr(lasterror));
360        end;        end;
361        state := wsbound;        state := wsbound;
362      end;      end;
# Line 303  Line 370 
370    
371  procedure tlsocket.listen;  procedure tlsocket.listen;
372  var  var
373    yes:longint;    yes,no:longint;
374    socktype:integer;    socktype:integer;
375    biniptemp:tbinip;    biniptemp:tbinip;
376    origaddr:string;    origaddr:string;
377  begin  begin
378    if state <> wsclosed then close;    if state <> wsclosed then close;
379    udp := uppercase(proto) = 'UDP';    udp := uppercase(proto) = 'UDP';
380    if udp then socktype := SOCK_DGRAM else socktype := SOCK_STREAM;    if udp then begin
381        socktype := SOCK_DGRAM;
382        dgram := true;
383      end else socktype := SOCK_STREAM;
384    origaddr := addr;    origaddr := addr;
385    
386    if addr = '' then begin    if addr = '' then begin
387      {$ifdef ipv6}      {$ifdef ipv6}
388        //writeln('ipv6 is defined');
389      if not v4listendefault then begin      if not v4listendefault then begin
390          //writeln('setting addr to ::');
391        addr := '::';        addr := '::';
392      end else      end else
393      {$endif}      {$endif}
394      addr := '0.0.0.0';      addr := '0.0.0.0';
395    end;    end;
396    biniptemp := forwardlookup(addr,10);    if isbiniplist(addr) then biniptemp := biniplist_get(addr,0) else biniptemp := forwardlookup(addr,10);
397    addr := ipbintostr(biniptemp);    addr := ipbintostr(biniptemp);
398      //writeln('after ipbintostr call addr =',addr);
399      //writeln('biniptemp.family =',biniptemp.family);
400      //writeln('AF_INET6=',AF_INET6);
401      //writeln('PF_INET6=',PF_INET6);
402      //writeln('AF_INET=',AF_INET);
403      //writeln('PF_INET=',PF_INET);
404      
405    fdhandlein := socket(biniptemp.family,socktype,0);    fdhandlein := socket(biniptemp.family,socktype,0);
406    {$ifdef ipv6}    {$ifdef ipv6}
407    if (addr = '::') and (origaddr = '') and (fdhandlein < 0) then begin    if (addr = '::') and (origaddr = '') and (fdhandlein < 0) then begin
408        writeln('failed to create an IPV6 socket with error ',socketerror,'. trying to create an IPV4 one instead');
409      addr := '0.0.0.0';      addr := '0.0.0.0';
410      fdhandlein := socket(AF_INET,socktype,0);      fdhandlein := socket(PF_INET,socktype,0);
411    end;    end;
412    {$endif}    {$endif}
413    if fdhandlein = -1 then raise ESocketException.create('unable to create socket');  
414      if fdhandlein = -1 then raise ESocketException.create('unable to create socket'{$ifdef win32}+' error='+inttostr(wsagetlasterror){$endif});
415    dupnowatch(fdhandlein); // sets up maxs and copies handle to fdhandleout among other things    dupnowatch(fdhandlein); // sets up maxs and copies handle to fdhandleout among other things
416    //eventcore.setfdreverse(fdhandlein,self); //already taken care of by dup    //eventcore.setfdreverse(fdhandlein,self); //already taken care of by dup
417    state := wsclosed; // then set this back as it was an undesired side effect of dup    state := wsclosed; // then set this back as it was an undesired side effect of dup
# Line 338  Line 419 
419    try    try
420      yes := $01010101;  {Copied this from existing code. Value is empiric,      yes := $01010101;  {Copied this from existing code. Value is empiric,
421                      but works. (yes=true<>0) }                      but works. (yes=true<>0) }
422        no := 0;
423      {$ifndef win32}      {$ifndef win32}
424        if SetSocketOptions(fdhandlein, SOL_SOCKET, SO_REUSEADDR,yes,sizeof(yes))=-1 then begin        if SetSocketOptions(fdhandlein, SOL_SOCKET, SO_REUSEADDR,yes,sizeof(yes))=-1 then begin
425          raise ESocketException.create('unable to set socket options');          raise ESocketException.create('unable to set SO_REUSEADDR socket option');
426          end;
427          //writeln('addr=',addr);
428          //writeln('setting IPV6_V6ONLY option to 0');
429          //allow v4 connections on v6 sockets
430          if biniptemp.family = af_inet6 then begin
431            if SetSocketOptions(fdhandlein, IPPROTO_IPV6,IPV6_V6ONLY,no,sizeof(no))=-1 then begin
432              writeln(IPPROTO_IPV6);
433              writeln(IPV6_V6ONLY);
434              raise ESocketException.create('unable to set IPV6_V6ONLY socket option error='+inttostr(socketerror));
435              
436            end;
437        end;        end;
438      {$endif}      {$endif}
439      localaddr := addr;      localaddr := addr;
# Line 350  Line 443 
443      if not udp then begin      if not udp then begin
444        {!!! allow custom queue length? default 5}        {!!! allow custom queue length? default 5}
445        if listenqueue = 0 then listenqueue := 5;        if listenqueue = 0 then listenqueue := 5;
446        If {$ifdef win32}winsock{$else}sockets{$endif}.Listen(fdhandlein,listenqueue)<>{$ifdef win32}0{$else}true{$endif} Then raise esocketexception.create('unable to listen');        If {$ifdef win32}winsock.listen{$else}system_listen{$endif}(fdhandlein,listenqueue)<>{$ifdef win32}0{$else}true{$endif} Then raise
447    esocketexception.create('unable to listen');
448        state := wsListening;        state := wsListening;
449      end else begin      end else begin
450        {$ifndef win32}        {$ifndef win32}
451          SetSocketOptions(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));          SetSocketOptions(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));
452          {$else}
453            SetSockOpt(fdhandleout, SOL_SOCKET, SO_BROADCAST, 'TRUE', Length('TRUE'));
454        {$endif}        {$endif}
455        state := wsconnected;        state := wsconnected;
456      end;      end;
457    
458        {$ifdef secondlistener}
459        //listening on ::. try to listen on 0.0.0.0 as well for platforms which don't already do that
460        if addr = '::' then begin
461          secondlistener := tlsocket.create(nil);
462          secondlistener.proto := proto;
463          secondlistener.addr := '0.0.0.0';
464          secondlistener.port := port;
465          if udp then begin
466            secondlistener.ondataavailable := secondaccepthandler;
467          end else begin
468            secondlistener.onsessionAvailable := secondaccepthandler;
469          end;
470          try
471            secondlistener.listen;
472          except
473            secondlistener.destroy;
474            secondlistener := nil;
475          end;
476        end;
477        {$endif}
478    finally    finally
479      if state = wsclosed then begin      if state = wsclosed then begin
480        if fdhandlein >= 0 then begin        if fdhandlein >= 0 then begin
# Line 375  Line 492 
492    //writeln('listened on addr '+addr+':'+port+' '+proto+' using socket number ',fdhandlein);    //writeln('listened on addr '+addr+':'+port+' '+proto+' using socket number ',fdhandlein);
493  end;  end;
494    
495    {$ifdef secondlistener}
496    procedure tlsocket.internalclose(error:word);
497    begin
498      if assigned(secondlistener) then begin
499        secondlistener.destroy;
500        secondlistener := nil;
501      end;
502      inherited internalclose(error);
503    end;
504    
505    procedure tlsocket.secondaccepthandler;
506    begin
507      lastsessionfromsecond := true;
508      if udp then begin
509        ondataavailable(self,error);
510      end else begin
511        if assigned(onsessionavailable) then onsessionavailable(self,error);
512      end;
513    end;
514    {$endif}
515    
516  function tlsocket.accept : longint;  function tlsocket.accept : longint;
517  var  var
518    FromAddrSize     : LongInt;        // i don't realy know what to do with these at this    FromAddrSize     : LongInt;        // i don't realy know what to do with these at this
519    FromAddr         : TInetSockAddrV;  // at this point time will tell :)    FromAddr         : TInetSockAddrV;  // at this point time will tell :)
520    a:integer;    a:integer;
521  begin  begin
522      {$ifdef secondlistener}
523      if (lastsessionfromsecond) then begin
524        lastsessionfromsecond := false;
525        result := secondlistener.accept;
526        exit;
527      end;
528      {$endif}
529    
530    FromAddrSize := Sizeof(FromAddr);    FromAddrSize := Sizeof(FromAddr);
531    {$ifdef win32}    {$ifdef win32}
532      result := winsock.accept(fdhandlein,@fromaddr,@fromaddrsize);      result := winsock.accept(fdhandlein,@fromaddr,@fromaddrsize);
533    {$else}    {$else}
534      result := sockets.accept(fdhandlein,fromaddr,fromaddrsize);      result := system_accept(fdhandlein,fromaddr,fromaddrsize);
535    {$endif}    {$endif}
536    //now we have accepted one request start monitoring for more again    //now we have accepted one request start monitoring for more again
537    eventcore.rmasterset(fdhandlein,true);    eventcore.rmasterset(fdhandlein,true);
# Line 402  Line 547 
547    end;    end;
548  end;  end;
549    
550    
551  function tlsocket.sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer;  function tlsocket.sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer;
552  var  var
553    destx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute dest;    {$ifdef ipv6}
554        realdest : tinetsockaddrv;
555        biniptemp : tbinip;
556      {$endif}
557      destx : {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif};
558    
559  begin  begin
560    result := {$ifdef win32}winsock{$else}sockets{$endif}.sendto(self.fdhandleout,data^,len,0,destx,destlen);    {$ifdef secondlistener}
561        if assigned(secondlistener) then if (dest.inaddr.family = AF_INET) then begin
562          result := secondlistener.sendto(dest,destlen,data,len);
563          exit;
564  end;  end;
565      {$endif}
566      {$ifdef ipv6}
567        if isv6socket then begin
568          biniptemp := inaddrvtobinip(dest);
569          converttov6(biniptemp);
570          destlen := makeinaddrv(biniptemp,inttostr(ntohs(dest.InAddr.port)),realdest);
571          destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@realdest)
572        end else begin
573          destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@dest)
574        end;
575      {$else}
576        destx := {$ifdef win32}winsock.pSockAddr{$else}pInetSockAddrV{$endif}(@dest)
577      {$endif}
578    
579      result := {$ifdef win32}winsock.sendto{$else}system_sendto{$endif}(self.fdhandleout,data^,len,0,destx^,destlen);
580    end;
581    
582    
583  function tlsocket.receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;var srclen:integer):integer;  function tlsocket.receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;var srclen:integer):integer;
584  var  var
585    srcx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute src;    tempsrc:TInetSockAddrV;
586      tempsrclen:integer;
587      srcx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute tempsrc;
588      biniptemp:tbinip;
589  begin  begin
590    result := {$ifdef win32}winsock{$else}sockets{$endif}.recvfrom(self.fdhandlein,data^,len,0,srcx,srclen);    {$ifdef secondlistener}
591      if assigned(secondlistener) then if lastsessionfromsecond then begin
592        lastsessionfromsecond := false;
593        result := secondlistener.receivefrom(data,len,src,srclen);
594        exit;
595      end;
596      {$endif}
597      tempsrclen := sizeof(tempsrc);
598      result := recvfrom(self.fdhandlein,data^,len,0,srcx,tempsrclen);
599    
600      {$ifdef ipv6}
601      biniptemp := inaddrvtobinip(tempsrc);
602      if needconverttov4(biniptemp) then begin
603        converttov4(biniptemp);
604        tempsrclen := makeinaddrv(biniptemp,inttostr(ntohs(tempsrc.InAddr.port)),tempsrc);
605      end;
606      {$endif}
607    
608      move(tempsrc,src,srclen);
609      srclen := tempsrclen;
610    end;
611    
612    procedure tlsocket.taskcallconnectionfailedhandler(wparam,lparam : longint);
613    begin
614      connectionfailedhandler(wparam);
615  end;  end;
616    
617  procedure tlsocket.connectionfailedhandler(error:word);  procedure tlsocket.connectionfailedhandler(error:word);
# Line 452  Line 650 
650      eventcore.rmasterclr(fdhandlein);      eventcore.rmasterclr(fdhandlein);
651      if assigned(onsessionAvailable) then onsessionAvailable(self,0);      if assigned(onsessionAvailable) then onsessionAvailable(self,0);
652    end;    end;
653    if udp and readtrigger then begin    if dgram and readtrigger then begin
654      if assigned(ondataAvailable) then ondataAvailable(self,0);      if assigned(ondataAvailable) then ondataAvailable(self,0);
655      {!!!test}      {!!!test}
656      exit;      exit;
# Line 510  Line 708 
708  end;  end;
709    
710    
711    
712  function tlsocket.getpeername(var addr:tsockaddrin;addrlen:integer):integer;  function tlsocket.getpeername(var addr:tsockaddrin;addrlen:integer):integer;
713  var  var
714    addrx : {$ifdef win32}winsock.tsockaddr{$else}tsockaddrin{$endif} absolute addr;    addrx : {$ifdef win32}winsock.tsockaddr{$else}tsockaddrin{$endif} absolute addr;
715  begin  begin
716    result := {$ifdef win32}winsock{$else}sockets{$endif}.getpeername(self.fdhandlein,addrx,addrlen);    result := {$ifdef win32}winsock.getpeername{$else}system_getpeername{$endif}(self.fdhandlein,addrx,addrlen);
717  end;  end;
718    
719  procedure tlsocket.getxaddrbin(var binip:tbinip);  procedure tlsocket.getxaddrbin(var binip:tbinip);
# Line 528  Line 727 
727    {$ifdef win32}    {$ifdef win32}
728      winsock.getsockname(self.fdhandlein,psockaddr(@addr)^,i);      winsock.getsockname(self.fdhandlein,psockaddr(@addr)^,i);
729    {$else}    {$else}
730      sockets.getsocketname(self.fdhandlein,addr,i);      getsocketname(self.fdhandlein,addr,i);
   {$endif}  
   binip.family := addr.inaddr.family;  
   {$ifdef ipv6}  
   if addr.inaddr6.sin6_family = AF_INET6 then begin  
     binip.ip6 := addr.inaddr6.sin6_addr;  
   end else  
731    {$endif}    {$endif}
732    begin    binip := inaddrvtobinip(addr);
     binip.ip := addr.inaddr.addr;  
   end;  
733    converttov4(binip);    converttov4(binip);
734  end;  end;
735    
# Line 552  Line 743 
743    {$ifdef win32}    {$ifdef win32}
744      winsock.getpeername(self.fdhandlein,psockaddr(@addr)^,i);      winsock.getpeername(self.fdhandlein,psockaddr(@addr)^,i);
745    {$else}    {$else}
746      sockets.getpeername(self.fdhandlein,addr,i);      system_getpeername(self.fdhandlein,addr,i);
747    {$endif}    {$endif}
748    
749    binip.family := addr.inaddr.family;    binip := inaddrvtobinip(addr);
   {$ifdef ipv6}  
   if addr.inaddr6.sin6_family = AF_INET6 then begin  
     binip.ip6 := addr.inaddr6.sin6_addr;  
   end else  
   {$endif}  
   begin  
     binip.ip := addr.inaddr.addr;  
   end;  
750    converttov4(binip);    converttov4(binip);
751  end;  end;
752    
# Line 595  Line 778 
778      winsock.getsockname(self.fdhandlein,psockaddrin(@addr)^,i);      winsock.getsockname(self.fdhandlein,psockaddrin(@addr)^,i);
779    
780    {$else}    {$else}
781      sockets.getsocketname(self.fdhandlein,addr,i);      getsocketname(self.fdhandlein,addr,i);
782    
783    {$endif}    {$endif}
784    result := inttostr(htons(addr.InAddr.port));    result := inttostr(htons(addr.InAddr.port));
# Line 611  Line 794 
794      winsock.getpeername(self.fdhandlein,psockaddrin(@addr)^,i);      winsock.getpeername(self.fdhandlein,psockaddrin(@addr)^,i);
795    
796    {$else}    {$else}
797      sockets.getpeername(self.fdhandlein,addr,i);      system_getpeername(self.fdhandlein,addr,i);
798    
799    {$endif}    {$endif}
800    result := inttostr(htons(addr.InAddr.port));    result := inttostr(htons(addr.InAddr.port));

Legend:
Removed from v.2  
changed lines
  Added in v.75

No admin address has been configured">No admin address has been configured
ViewVC Help
Powered by ViewVC 1.1.22