secondlistener
authorbeware <beware@bircd.org>
Mon, 31 Mar 2008 00:30:30 +0000 (00:30 +0000)
committerbeware <beware@bircd.org>
Mon, 31 Mar 2008 00:30:30 +0000 (00:30 +0000)
git-svn-id: file:///svnroot/lcore/trunk@11 b1de8a11-f9be-4011-bde0-cc7ace90066a

lsocket.pas

index c37a66aaa93b76f18075c0a247c8ca7dc5e99b83..ffd411f6b743ed99cb8fc5b3149d13d0c7a903e2 100755 (executable)
@@ -54,6 +54,14 @@ interface
       sockets,\r
     {$endif}\r
     classes,{pgdebugout,}pgtypes,lcore,fd_utils,binipstuff,dnssync;\r
+\r
+{$ifdef ipv6}\r
+{$define secondlistener}\r
+const\r
+  v4listendefault:boolean=false;\r
+{$endif}\r
+\r
+\r
 type\r
   sunB = packed record\r
     s_b1, s_b2, s_b3, s_b4: byte;\r
@@ -94,6 +102,12 @@ type
       proto:string;\r
       udp:boolean;\r
       listenqueue:integer;\r
+      {$ifdef secondlistener}\r
+      secondlistener:tlsocket;\r
+      lastsessionfromsecond:boolean;\r
+      procedure secondaccepthandler(sender:tobject;error:word);\r
+      procedure internalclose(error:word);override;\r
+      {$endif}\r
       procedure connectionfailedhandler(error:word);\r
       procedure connecttimeouthandler(sender:tobject);\r
       procedure connectsuccesshandler;\r
@@ -105,7 +119,7 @@ type
       function accept : longint;\r
       function sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:integer):integer; virtual;\r
       function receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;var srclen:integer):integer; virtual;\r
-      //procedure internalclose(error:word);override;\r
+\r
       procedure handlefdtrigger(readtrigger,writetrigger:boolean); override;\r
       function send(data:pointer;len:integer):integer;override;\r
       procedure sendstr(const str : string);override;\r
@@ -131,12 +145,6 @@ type
 \r
 {!!!function longipdns(s:string):longint;}\r
 \r
-{$ifdef ipv6}\r
-const\r
-  v4listendefault:boolean=false;\r
-{$endif}\r
-\r
-\r
 const\r
   TCP_NODELAY=1;\r
   IPPROTO_TCP=6;\r
@@ -260,7 +268,13 @@ end;
 function tlsocket.receive(Buf:Pointer;BufSize:integer):integer;\r
 begin\r
   if udp then begin\r
-    result := myfdread(self.fdhandlein,buf^,bufsize);\r
+    {$ifdef secondlistener}\r
+    if lastsessionfromsecond then begin\r
+      result := secondlistener.receive(buf,bufsize);\r
+      lastsessionfromsecond := false;\r
+    end else\r
+    {$endif}\r
+      result := myfdread(self.fdhandlein,buf^,bufsize);\r
   end else begin\r
     result := inherited receive(buf,bufsize);\r
   end;\r
@@ -329,6 +343,7 @@ begin
     fdhandlein := socket(AF_INET,socktype,0);\r
   end;\r
   {$endif}\r
+\r
   if fdhandlein = -1 then raise ESocketException.create('unable to create socket');\r
   dupnowatch(fdhandlein); // sets up maxs and copies handle to fdhandleout among other things\r
   //eventcore.setfdreverse(fdhandlein,self); //already taken care of by dup\r
@@ -357,6 +372,22 @@ begin
       {$endif}\r
       state := wsconnected;\r
     end;\r
+\r
+    {$ifdef secondlistener}\r
+    //listening on ::. try to listen on 0.0.0.0 as well for platforms which don't already do that\r
+    if addr = '::' then begin\r
+      secondlistener := tlsocket.create(nil);\r
+      secondlistener.proto := proto;\r
+      secondlistener.addr := '0.0.0.0';\r
+      secondlistener.port := port;\r
+      if udp then begin\r
+        secondlistener.ondataavailable := secondaccepthandler;\r
+      end else begin\r
+        secondlistener.onsessionAvailable := secondaccepthandler;\r
+      end;\r
+      secondlistener.listen;\r
+    end;\r
+    {$endif}\r
   finally\r
     if state = wsclosed then begin\r
       if fdhandlein >= 0 then begin\r
@@ -374,12 +405,37 @@ begin
   //writeln('listened on addr '+addr+':'+port+' '+proto+' using socket number ',fdhandlein);\r
 end;\r
 \r
+{$ifdef secondlistener}\r
+procedure tlsocket.internalclose(error:word);\r
+begin\r
+  if assigned(secondlistener) then secondlistener.destroy;\r
+  inherited internalclose(error);\r
+end;\r
+\r
+procedure tlsocket.secondaccepthandler;\r
+begin\r
+  lastsessionfromsecond := true;\r
+  if udp then begin\r
+    ondataavailable(self,error);\r
+  end else begin\r
+    if assigned(onsessionavailable) then onsessionavailable(self,error);\r
+  end;\r
+end;\r
+{$endif}\r
+\r
 function tlsocket.accept : longint;\r
 var\r
   FromAddrSize     : LongInt;        // i don't realy know what to do with these at this\r
   FromAddr         : TInetSockAddrV;  // at this point time will tell :)\r
   a:integer;\r
 begin\r
+  {$ifdef secondlistener}\r
+  if (lastsessionfromsecond) then begin\r
+    lastsessionfromsecond := false;\r
+    result := secondlistener.accept;\r
+    exit;\r
+  end;\r
+  {$endif}\r
 \r
   FromAddrSize := Sizeof(FromAddr);\r
   {$ifdef win32}\r
@@ -405,6 +461,12 @@ function tlsocket.sendto(dest:TInetSockAddrV;destlen:integer;data:pointer;len:in
 var\r
   destx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute dest;\r
 begin\r
+  {$ifdef secondlistener}\r
+  if assigned(secondlistener) then if (dest.inaddr.family = AF_INET) then begin\r
+    result := secondlistener.sendto(dest,destlen,data,len);\r
+    exit;\r
+  end;\r
+  {$endif}\r
   result := {$ifdef win32}winsock{$else}sockets{$endif}.sendto(self.fdhandleout,data^,len,0,destx,destlen);\r
 end;\r
 \r
@@ -412,6 +474,13 @@ function tlsocket.receivefrom(data:pointer;len:integer;var src:TInetSockAddrV;va
 var\r
   srcx : {$ifdef win32}winsock.TSockAddr{$else}TInetSockAddrV{$endif} absolute src;\r
 begin\r
+  {$ifdef secondlistener}\r
+  if assigned(secondlistener) then if lastsessionfromsecond then begin\r
+    lastsessionfromsecond := false;\r
+    result := secondlistener.receivefrom(data,len,src,srclen);\r
+    exit;\r
+  end;\r
+  {$endif}\r
   result := {$ifdef win32}winsock{$else}sockets{$endif}.recvfrom(self.fdhandlein,data^,len,0,srcx,srclen);\r
 end;\r
 \r
@@ -630,6 +699,6 @@ end;
     result := winsock.recv(fd,buf,size,0);\r
   end;\r
 {$endif}\r
-\r
+
 end.\r
 \r