Index: ssfpc.inc =================================================================== --- ssfpc.inc (revision 209) +++ ssfpc.inc (working copy) @@ -67,6 +67,9 @@ {$ifdef darwin} {$DEFINE SOCK_HAS_SINLEN} // BSD definition of scoketaddr {$endif} +{$ifdef haiku} +{$DEFINE SOCK_HAS_SINLEN} // BSD definition of scoketaddr +{$endif} interface @@ -103,7 +106,9 @@ const FIONREAD = termio.FIONREAD; FIONBIO = termio.FIONBIO; +{$IFNDEF HAIKU} FIOASYNC = termio.FIOASYNC; +{$ENDIF} const IPPROTO_IP = 0; { Dummy } @@ -212,12 +217,21 @@ SOMAXCONN = 1024; +{$IFDEF HAIKU} + IPV6_UNICAST_HOPS = 27; +{$ELSE} IPV6_UNICAST_HOPS = sockets.IPV6_UNICAST_HOPS; +{$ENDIF} IPV6_MULTICAST_IF = sockets.IPV6_MULTICAST_IF; IPV6_MULTICAST_HOPS = sockets.IPV6_MULTICAST_HOPS; IPV6_MULTICAST_LOOP = sockets.IPV6_MULTICAST_LOOP; +{$IFDEF HAIKU} + IPV6_JOIN_GROUP = 28; + IPV6_LEAVE_GROUP = 29; +{$ELSE} IPV6_JOIN_GROUP = sockets.IPV6_JOIN_GROUP; IPV6_LEAVE_GROUP = sockets.IPV6_LEAVE_GROUP; +{$ENDIF} const SOCK_STREAM = 1; { stream socket } @@ -231,9 +245,9 @@ { Address families. } - AF_UNSPEC = 0; { unspecified } - AF_INET = 2; { internetwork: UDP, TCP, etc. } - AF_INET6 = 10; { Internetwork Version 6 } + AF_UNSPEC = 0; { unspecified } + AF_INET = sockets.AF_INET; { internetwork: UDP, TCP, etc. } + AF_INET6 = sockets.AF_INET6; { Internetwork Version 6 } AF_MAX = 24; { Protocol families, same as address families for now. } @@ -254,15 +268,31 @@ MSG_OOB = sockets.MSG_OOB; // Process out-of-band data. MSG_PEEK = sockets.MSG_PEEK; // Peek at incoming messages. - {$ifdef DARWIN} + {$if defined(DARWIN)} MSG_NOSIGNAL = $20000; // Do not generate SIGPIPE. // Works under MAC OS X, but is undocumented, // So FPC doesn't include it + {$elseif defined(HAIKU)} + MSG_NOSIGNAL = $0800; {$else} - MSG_NOSIGNAL = sockets.MSG_NOSIGNAL; // Do not generate SIGPIPE. + MSG_NOSIGNAL = sockets.MSG_NOSIGNAL; // Do not generate SIGPIPE. {$endif} +{$IF DEFINED(HAIKU)} const + ESysESTALE = (B_POSIX_ERROR_BASE + 40); + ESysENOTSOCK = (B_POSIX_ERROR_BASE + 44); + ESysEHOSTDOWN = (B_POSIX_ERROR_BASE + 45); + ESysEDESTADDRREQ = (B_POSIX_ERROR_BASE + 48); + ESysEDQUOT = (B_POSIX_ERROR_BASE + 49); + // Fake error codes + ESysEUSERS = (B_POSIX_ERROR_BASE + 128); + ESysEREMOTE = (B_POSIX_ERROR_BASE + 129); + ESysETOOMANYREFS = (B_POSIX_ERROR_BASE + 130); + ESysESOCKTNOSUPPORT = (B_POSIX_ERROR_BASE + 131); +{$ENDIF} + +const WSAEINTR = ESysEINTR; WSAEBADF = ESysEBADF; WSAEACCES = ESysEACCES; @@ -755,7 +785,7 @@ begin Result := 0; FillChar(Sin, Sizeof(Sin), 0); - Sin.sin_port := Resolveport(port, family, SockProtocol, SockType); + Sin.sin_port := htons(Resolveport(port, family, SockProtocol, SockType)); TwoPass := False; if Family = AF_UNSPEC then begin @@ -858,7 +888,7 @@ ProtoEnt: TProtocolEntry; ServEnt: TServiceEntry; begin - Result := synsock.htons(StrToIntDef(Port, 0)); + Result := StrToIntDef(Port, 0); if Result = 0 then begin ProtoEnt.Name := ''; @@ -865,7 +895,7 @@ GetProtocolByNumber(SockProtocol, ProtoEnt); ServEnt.port := 0; GetServiceByName(Port, ProtoEnt.Name, ServEnt); - Result := ServEnt.port; + Result := ntohs(ServEnt.port); end; end; Index: blcksock.pas =================================================================== --- blcksock.pas (revision 278) +++ blcksock.pas (working copy) @@ -1234,6 +1234,8 @@ TCustomSSL = class(TObject) private protected + FSessionOld: Pointer; + FSessionNew: Pointer; FOnVerifyCert: THookVerifyCert; FSocket: TTCPBlockSocket; FSSLEnabled: Boolean; @@ -1368,6 +1370,9 @@ {:Return error description of last SSL operation.} property LastErrorDesc: string read FLastErrorDesc; + + {:Used for session resumption } + property Session: Pointer read FSessionNew write FSessionOld; published {:Here you can specify requested SSL/TLS mode. Default is autodetection, but on some servers autodetection not working properly. In this case you must @@ -2518,6 +2523,8 @@ begin repeat s := RecvPacket(Timeout); + if (Length(s) = 0) then + Break; if FLastError = 0 then WriteStrToStream(Stream, s); until FLastError <> 0; Index: ftpsend.pas =================================================================== --- ftpsend.pas (revision 209) +++ ftpsend.pas (working copy) @@ -870,6 +870,11 @@ end; FDSock.CloseSocket; FDSock.Bind(FIPInterface, cAnyPort); + + if FIsDataTLS then begin + FDSock.SSL.Session := FSock.SSL.Session; + end; + FDSock.Connect(FDataIP, FDataPort); Result := FDSock.LastError = 0; end Index: ssl_openssl.pas =================================================================== --- ssl_openssl.pas (revision 278) +++ ssl_openssl.pas (working copy) @@ -77,8 +77,9 @@ accepting of new connections! } -{$INCLUDE 'jedi.inc'} - +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} {$H+} {$IFDEF UNICODE} @@ -86,7 +87,7 @@ {$WARN IMPLICIT_STRING_CAST_LOSS OFF} {$ENDIF} -unit ssl_openssl{$IFDEF SUPPORTS_DEPRECATED} deprecated{$IFDEF SUPPORTS_DEPRECATED_DETAILS} 'Use ssl_openssl3 with OpenSSL 3.0 instead'{$ENDIF}{$ENDIF}; +unit ssl_openssl; interface @@ -495,6 +496,11 @@ function TSSLOpenSSL.DeInit: Boolean; begin Result := True; + if Assigned(FSessionNew) then + begin + SslSessionFree(FSessionNew); + FSessionNew := nil; + end; if assigned (Fssl) then sslfree(Fssl); Fssl := nil; @@ -538,6 +544,10 @@ SSLCheck; Exit; end; + // Reuse session + if Assigned(FSessionOld) then begin + SslSetSession(Fssl, FSessionOld); + end; if SNIHost<>'' then begin SSLCtrl(Fssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, PAnsiChar(AnsiString(SNIHost))); @@ -579,6 +589,9 @@ FSSLEnabled := True; Result := True; end; + if Result and (FSessionOld = nil) then begin + FSessionNew := SslGet1Session(Fssl); + end; end; function TSSLOpenSSL.Accept: boolean; Index: ssl_openssl_lib.pas =================================================================== --- ssl_openssl_lib.pas (revision 278) +++ ssl_openssl_lib.pas (working copy) @@ -813,6 +813,9 @@ function SSLGetVerifyResult(ssl: PSSL):Integer; function SSLCtrl(ssl: PSSL; cmd: integer; larg: integer; parg: SslPtr):Integer; function SslSet1Host(ssl: PSSL; hostname: PAnsiChar):Integer; + procedure SslSessionFree(session: PSslPtr); + function SslGet1Session(ssl: PSSL):PSslPtr; + function SslSetSession(ssl: PSSL; session: PSslPtr): Integer; // libeay.dll function X509New: PX509; @@ -940,6 +943,9 @@ TSSLGetVerifyResult = function(ssl: PSSL):Integer; cdecl; TSSLCtrl = function(ssl: PSSL; cmd: integer; larg: integer; parg: SslPtr):Integer; cdecl; TSslSet1Host = function(ssl: PSSL; hostname: PAnsiChar):Integer; cdecl; + TSslSessionFree = procedure(session: PSslPtr); cdecl; + TSslGet1Session = function(ssl: PSSL):PSslPtr; cdecl; + TSslSetSession = function(ssl: PSSL; session: PSslPtr): Integer; cdecl; TSSLSetTlsextHostName = function(ssl: PSSL; buf: PAnsiChar):Integer; cdecl; @@ -1049,6 +1055,9 @@ _SSLGetVerifyResult: TSSLGetVerifyResult = nil; _SSLCtrl: TSSLCtrl = nil; _SslSet1Host: TSslSet1Host = nil; + _SslSessionFree: TSslSessionFree = nil; + _SslGet1Session: TSslGet1Session = nil; + _SslSetSession: TSslSetSession = nil; // libeay.dll _X509New: TX509New = nil; @@ -1474,6 +1483,28 @@ Result := 0; end; +procedure SslSessionFree(session: PSslPtr); +begin + if InitSSLInterface and Assigned(_SslSessionFree) then + _SslSessionFree(session); +end; + +function SslGet1Session(ssl: PSSL): PSslPtr; +begin + if InitSSLInterface and Assigned(_SslGet1Session) then + Result := _SslGet1Session(ssl) + else + Result := nil; +end; + +function SslSetSession(ssl: PSSL; session: PSslPtr): Integer; +begin + if InitSSLInterface and Assigned(_SslSetSession) then + Result := _SslSetSession(ssl, session) + else + Result := 0; +end; + // libeay.dll function X509New: PX509; begin @@ -1924,7 +1955,7 @@ {$ENDIF} end; -function GetLibFileName(Handle: THandle): string; +function GetLibFileName(Handle: TLibHandle): string; var n: integer; begin @@ -2022,6 +2053,9 @@ _SslGetVerifyResult := GetProcAddr(SSLLibHandle, 'SSL_get_verify_result'); _SslCtrl := GetProcAddr(SSLLibHandle, 'SSL_ctrl'); _SslSet1Host := GetProcAddr(SSLLibHandle, 'SSL_set1_host'); + _SslSessionFree := GetProcAddr(SSLLibHandle, 'SSL_SESSION_free'); + _SslGet1Session := GetProcAddr(SSLLibHandle, 'SSL_get1_session'); + _SslSetSession := GetProcAddr(SSLLibHandle, 'SSL_set_session'); _X509New := GetProcAddr(SSLUtilHandle, 'X509_new'); _X509Free := GetProcAddr(SSLUtilHandle, 'X509_free'); @@ -2213,6 +2247,9 @@ _SslGetVerifyResult := nil; _SslCtrl := nil; _SslSet1Host := nil; + _SslSessionFree := nil; + _SslGet1Session := nil; + _SslSetSession := nil; _X509New := nil; _X509Free := nil;