Browse Source

* Amiga needs exact address size.

Michaël Van Canneyt 1 week ago
parent
commit
aaa50b7cbd
2 changed files with 84 additions and 35 deletions
  1. 61 30
      packages/fcl-net/src/fpsockets.pp
  2. 23 5
      packages/fcl-net/src/ssockets.pp

+ 61 - 30
packages/fcl-net/src/fpsockets.pp

@@ -18,6 +18,13 @@ unit fpsockets;
 {$mode ObjFPC}{$H+}
 {$mode ObjFPC}{$H+}
 {$TypedAddress on}
 {$TypedAddress on}
 {$modeswitch advancedrecords}
 {$modeswitch advancedrecords}
+{$macro on}
+
+{$IFDEF FPC_DOTTEDUNITS}
+{$define socketsunit:=System.Net.Sockets}
+{$ELSE FPC_DOTTEDUNITS}
+{$define socketsunit:=sockets}
+{$ENDIF FPC_DOTTEDUNITS}
 
 
 interface
 interface
 
 
@@ -221,8 +228,14 @@ function ConnectionState(const ASocket: TFPSocket): TConnectionState;
 
 
 type
 type
   PAddressUnion = ^TAddressUnion;
   PAddressUnion = ^TAddressUnion;
+
+  { TAddressUnion }
+
   TAddressUnion = record
   TAddressUnion = record
-  case TFPSocketType of
+    function GetAddr : socketsunit.psockaddr;
+    function GetAddrSize : cint;
+    procedure GetAddrAndSize(out aAddr: socketsunit.pSockAddr;out aSize: cint);
+  case SocketType : TFPSocketType of
     stIPv4: (In4Addr: sockaddr_in);
     stIPv4: (In4Addr: sockaddr_in);
     stIPv6: (In6Addr: sockaddr_in6);
     stIPv6: (In6Addr: sockaddr_in6);
     stUnixSocket: (UnixAddr: sockaddr_un);
     stUnixSocket: (UnixAddr: sockaddr_un);
@@ -245,13 +258,6 @@ uses
   math;
   math;
 {$ENDIF FPC_DOTTEDUNITS}
 {$ENDIF FPC_DOTTEDUNITS}
 
 
-{$macro on}
-{$IFDEF FPC_DOTTEDUNITS}
-{$define socketsunit:=System.Net.Sockets}
-{$ELSE FPC_DOTTEDUNITS}
-{$define socketsunit:=sockets}
-{$ENDIF FPC_DOTTEDUNITS}
-
 { Helper }
 { Helper }
 
 
 const
 const
@@ -286,12 +292,14 @@ begin
     AAddress := IN4MappedIN6Address(AAddress.Address);
     AAddress := IN4MappedIN6Address(AAddress.Address);
   if AAddress.AddressType = atIN4 then
   if AAddress.AddressType = atIN4 then
   begin
   begin
+    Result.SocketType:=stIPv4;
     Result.In4Addr.sin_family := AF_INET;
     Result.In4Addr.sin_family := AF_INET;
     Result.In4Addr.sin_port := HToNS(APort);
     Result.In4Addr.sin_port := HToNS(APort);
     Result.In4Addr.sin_addr.s_addr := LongWord(StrToNetAddr(AAddress.Address));
     Result.In4Addr.sin_addr.s_addr := LongWord(StrToNetAddr(AAddress.Address));
   end
   end
   else if AAddress.AddressType = atIN6 then
   else if AAddress.AddressType = atIN6 then
   begin
   begin
+    Result.SocketType:=stIPv6;
     Result.In6Addr.sin6_family := AF_INET6;
     Result.In6Addr.sin6_family := AF_INET6;
     Result.In6Addr.sin6_port := HToNS(APort);
     Result.In6Addr.sin6_port := HToNS(APort);
     Result.In6Addr.sin6_addr := StrToHostAddr6(AAddress.Address);
     Result.In6Addr.sin6_addr := StrToHostAddr6(AAddress.Address);
@@ -300,6 +308,7 @@ begin
   end
   end
   else if AAddress.AddressType = atUnixSock then
   else if AAddress.AddressType = atUnixSock then
   begin
   begin
+    Result.SocketType:=stUnixSocket;
     if Length(AAddress.Address) > SizeOf(Result.UnixAddr.sun_path)-1 then
     if Length(AAddress.Address) > SizeOf(Result.UnixAddr.sun_path)-1 then
       raise EUnsupportedAddress.Create('Unix address should be at most 108 characters');
       raise EUnsupportedAddress.Create('Unix address should be at most 108 characters');
     Result.UnixAddr.sun_family := AF_UNIX;
     Result.UnixAddr.sun_family := AF_UNIX;
@@ -540,11 +549,14 @@ procedure Bind(const ASocket: TFPSocket; const AAddress: TNetworkAddress;
 var
 var
   enableReuse: Integer = 1;
   enableReuse: Integer = 1;
   addr: TAddressUnion;
   addr: TAddressUnion;
+  addrptr : socketsunit.psockaddr;
+  addrlen : cint;
 begin
 begin
   if ReuseAddr then
   if ReuseAddr then
     fpsetsockopt(ASocket.FD, SOL_SOCKET, SO_REUSEADDR, @enableReuse, SizeOf(enableReuse));
     fpsetsockopt(ASocket.FD, SOL_SOCKET, SO_REUSEADDR, @enableReuse, SizeOf(enableReuse));
   addr := CreateAddr(AAddress, APort, ASocket.SocketType = stIPDualStack);
   addr := CreateAddr(AAddress, APort, ASocket.SocketType = stIPDualStack);
-  if fpbind(ASocket.FD, socketsunit.PSockAddr(@addr), SizeOf(addr)) <> 0 then raise
+  addr.GetAddrAndSize(addrptr,addrlen);
+  if fpbind(ASocket.FD, addrptr, addrlen) <> 0 then raise
     ESocketCodeError.Create(socketerror, 'bind (%s:%d)'.Format([AAddress.Address, APort]));
     ESocketCodeError.Create(socketerror, 'bind (%s:%d)'.Format([AAddress.Address, APort]));
 end;
 end;
 
 
@@ -557,7 +569,7 @@ end;
 function AcceptConnection(const ASocket: TFPSocket): TFPSocketConnection;
 function AcceptConnection(const ASocket: TFPSocket): TFPSocketConnection;
 var
 var
   addr: TAddressUnion;
   addr: TAddressUnion;
-  addrLen: TSocklen = SizeOf(addr);
+  addrLen: TSocklen;
 begin
 begin
   Result.Socket.FD := fpaccept(ASocket.FD, socketsunit.psockaddr(@addr), @addrLen);
   Result.Socket.FD := fpaccept(ASocket.FD, socketsunit.psockaddr(@addr), @addrLen);
   if SocketInvalid(Result.Socket.FD) then
   if SocketInvalid(Result.Socket.FD) then
@@ -588,8 +600,8 @@ function Connect(const ASocket: TFPSocket; const AAddress: TNetworkAddress;
   APort: Word): TConnectionState;
   APort: Word): TConnectionState;
 var
 var
   addr: TAddressUnion;
   addr: TAddressUnion;
-  addrlen : cint;
-  addrptr : socketsunit.psockaddr;
+  AddrLen : cint;
+  addrPtr : socketsunit.psockaddr;
 
 
 const
 const
   {$IFDEF WINDOWS} 
   {$IFDEF WINDOWS} 
@@ -617,24 +629,7 @@ const
   {$ENDIF}
   {$ENDIF}
 begin
 begin
   addr := CreateAddr(AAddress, APort, ASocket.SocketType = stIPDualStack);
   addr := CreateAddr(AAddress, APort, ASocket.SocketType = stIPDualStack);
-  case ASocket.SocketType of
-    stIPv4,
-    stIPDualStack:
-      begin
-      addrlen:=sizeof(sockaddr_in);
-      addrptr:=psockaddr(@addr.In4Addr);
-      end;
-    stIPv6 :
-      begin
-      addrlen:=sizeof(sockaddr_in6);
-      addrptr:=psockaddr(@addr.In6Addr);
-      end;
-    stUnixSocket :
-      begin
-      addrlen:=sizeof(sockaddr_un);
-      addrptr:=psockaddr(@addr.UnixAddr);
-      end;
-  end;
+  Addr.GetAddrAndSize(addrPtr,AddrLen);
   if fpconnect(ASocket.FD, addrptr, addrlen) <> 0 then
   if fpconnect(ASocket.FD, addrptr, addrlen) <> 0 then
     case socketerror of
     case socketerror of
     EALREADY,
     EALREADY,
@@ -1265,5 +1260,41 @@ begin
   FExpectedSize := AExpected;
   FExpectedSize := AExpected;
 end;
 end;
 
 
+{ TAddressUnion }
+
+function TAddressUnion.GetAddr: socketsunit.psockaddr;
+begin
+  case SocketType of
+    stIPv4,
+    stIPDualStack:
+      Result:=psockaddr(@self.In4Addr);
+    stIPv6 :
+      Result:=psockaddr(@self.In6Addr);
+    stUnixSocket :
+      result:=psockaddr(@self.UnixAddr);
+  end;
+
+end;
+
+function TAddressUnion.GetAddrSize: cint;
+
+begin
+  case SocketType of
+  stIPv4,
+  stIPDualStack:
+    Result:=sizeof(sockaddr_in);
+  stIPv6 :
+    Result:=sizeof(sockaddr_in6);
+  stUnixSocket :
+    Result:=sizeof(sockaddr_un);
+  end;
+end;
+
+procedure TAddressUnion.GetAddrAndSize(out aAddr: socketsunit.pSockAddr;out aSize: cint);
+begin
+  aAddr:=GetAddr;
+  aSize:=GetAddrSize;
+end;
+
 end.
 end.
 
 

+ 23 - 5
packages/fcl-net/src/ssockets.pp

@@ -17,6 +17,14 @@
 unit ssockets;
 unit ssockets;
 {$ENDIF FPC_DOTTEDUNITS}
 {$ENDIF FPC_DOTTEDUNITS}
 
 
+{$macro on}
+
+{$IFDEF FPC_DOTTEDUNITS}
+{$define socketsunit:=System.Net.Sockets}
+{$ELSE FPC_DOTTEDUNITS}
+{$define socketsunit:=sockets}
+{$ENDIF FPC_DOTTEDUNITS}
+
 interface
 interface
 
 
 {$IFDEF FPC_DOTTEDUNITS}
 {$IFDEF FPC_DOTTEDUNITS}
@@ -1398,9 +1406,12 @@ end;
 procedure TInetServer.Bind;
 procedure TInetServer.Bind;
 var
 var
   naddr: TAddressUnion;
   naddr: TAddressUnion;
+  addrPtr : socketsunit.psockaddr;
+  addrSize : cint;
 begin
 begin
   naddr:=CreateAddr(FEndPoint.First,FEndPoint.Second,FSocket.SocketType=stIPDualStack);
   naddr:=CreateAddr(FEndPoint.First,FEndPoint.Second,FSocket.SocketType=stIPDualStack);
-  if {$IFDEF FPC_DOTTEDUNITS}System.Net.{$ENDIF}Sockets.fpBind(FSocket.FD, @naddr, Sizeof(naddr))<>0 then
+  naddr.GetAddrAndSize(addrPtr,addrSize);
+  if {$IFDEF FPC_DOTTEDUNITS}System.Net.{$ENDIF}Sockets.fpBind(FSocket.FD, addrPtr, addrSize)<>0 then
     raise ESocketError.Create(seBindFailed, [IntToStr(FEndPoint.Second)]);
     raise ESocketError.Create(seBindFailed, [IntToStr(FEndPoint.Second)]);
   FBound:=True;
   FBound:=True;
 end;
 end;
@@ -1437,20 +1448,23 @@ end;
 function TInetServer.AcceptSocket:TFPSocket;
 function TInetServer.AcceptSocket:TFPSocket;
 
 
 Var
 Var
-  L : longint;
+  addrSize : cint;
+  addrPtr : socketsunit.psockaddr;
   R : integer;
   R : integer;
   naddr: TAddressUnion;
   naddr: TAddressUnion;
 begin
 begin
   // Is basically the same except that the handle will be overwritten
   // Is basically the same except that the handle will be overwritten
   Result:=FSocket;
   Result:=FSocket;
-  L:=SizeOf(naddr);
 {$IFDEF UNIX}
 {$IFDEF UNIX}
   R:=ESysEINTR;
   R:=ESysEINTR;
+  // need to set this so ptr/addrsize are correct.
+  naddr.SocketType:=Result.SocketType;
+  naddr.GetAddrAndSize(AddrPtr,addrSize);
   Result.FD:=-1;
   Result.FD:=-1;
   While SocketInvalid(Result.FD) and (R=ESysEINTR) do
   While SocketInvalid(Result.FD) and (R=ESysEINTR) do
 {$ENDIF UNIX}
 {$ENDIF UNIX}
    begin
    begin
-   Result.FD:={$IFDEF FPC_DOTTEDUNITS}System.Net.{$ENDIF}Sockets.fpAccept(FSocket.FD,@naddr,@L);
+   Result.FD:={$IFDEF FPC_DOTTEDUNITS}System.Net.{$ENDIF}Sockets.fpAccept(FSocket.FD,addrptr,@addrSize);
    R:=SocketError;
    R:=SocketError;
    end;
    end;
 {$ifdef Unix}
 {$ifdef Unix}
@@ -1690,6 +1704,8 @@ Const
 
 
 Var
 Var
   addr: TAddressUnion;
   addr: TAddressUnion;
+  addrSize : cint;
+  addrPtr : socketsunit.psockaddr;
   IsError : Boolean;
   IsError : Boolean;
   TimeOutResult : TCheckTimeOutResult;
   TimeOutResult : TCheckTimeOutResult;
   Err: Integer;
   Err: Integer;
@@ -1711,11 +1727,13 @@ begin
         addr.In4Addr.sin_family := AF_INET;
         addr.In4Addr.sin_family := AF_INET;
         addr.In4Addr.sin_port := ShortHostToNet(FEndPoint.Second);
         addr.In4Addr.sin_port := ShortHostToNet(FEndPoint.Second);
         addr.In4Addr.sin_addr.s_addr := HostToNet(HostAddress.s_addr);
         addr.In4Addr.sin_addr.s_addr := HostToNet(HostAddress.s_addr);
+        addr.SocketType:=stIPv4;
       finally
       finally
         free;
         free;
       end
       end
   else
   else
     addr:=CreateAddr(FEndPoint.First,FEndPoint.Second,FSocket.SocketType=stIPDualStack);
     addr:=CreateAddr(FEndPoint.First,FEndPoint.Second,FSocket.SocketType=stIPDualStack);
+  Addr.GetAddrAndSize(addrPtr,addrSize);
 {$IFDEF HAVENONBLOCKING}
 {$IFDEF HAVENONBLOCKING}
   if ConnectTimeOut>0 then
   if ConnectTimeOut>0 then
     SetSocketBlockingMode(Handle, bmNonBlocking, @FDS) ;
     SetSocketBlockingMode(Handle, bmNonBlocking, @FDS) ;
@@ -1727,7 +1745,7 @@ begin
   While IsError and ((Err=ESysEINTR) or (Err=ESysEAGAIN)) do
   While IsError and ((Err=ESysEINTR) or (Err=ESysEAGAIN)) do
   {$endif}
   {$endif}
     begin
     begin
-    IsError:=fpConnect(Handle, @addr, sizeof(addr))<>0;
+    IsError:=fpConnect(Handle, addrPtr, addrSize)<>0;
     if IsError then
     if IsError then
       Err:=Socketerror;
       Err:=Socketerror;
     end;
     end;