Recent

Author Topic: Patch proposition for socket.pp problem under openbsd (gitlab ticket #38188)  (Read 3407 times)

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Hello.
After, many tests, root cause identified:

OpenBSD sockaddr_in ABI requires:

* sin_len : byte
* sin_family : byte

Current RTL TInetSockAddr uses Linux-style layout:
sin_family : word

This shifts sockaddr fields and causes bind() to fail with errno 47 (EAFNOSUPPORT).

Adding packed record OpenBSD layout + sin_len initialization fixes fpBind().

this is a patch
Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/unix/sockets.pp b/rtl/unix/sockets.pp
  2. index XXXXXXX..YYYYYYY 100644
  3. --- a/rtl/unix/sockets.pp
  4. +++ b/rtl/unix/sockets.pp
  5. @@ -120,11 +120,20 @@ type
  6.    in_addr = record
  7.      s_addr : cuint32;
  8.    end;
  9.  
  10. +{$ifdef openbsd}
  11. +  TInetSockAddr = packed record
  12. +    sin_len    : byte;
  13. +    sin_family : byte;
  14. +    sin_port   : word;
  15. +    sin_addr   : in_addr;
  16. +    sin_zero   : array[0..7] of char;
  17. +  end;
  18. +{$else}
  19.    TInetSockAddr = packed record
  20.      sin_family : word;
  21.      sin_port   : word;
  22.      sin_addr   : in_addr;
  23.      sin_zero   : array[0..7] of char;
  24.    end;
  25. +{$endif}
  26.  


and

Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/unix/syssocket.inc b/rtl/unix/syssocket.inc
  2. index XXXXXXX..YYYYYYY 100644
  3. --- a/rtl/unix/syssocket.inc
  4. +++ b/rtl/unix/syssocket.inc
  5. @@ -45,6 +45,10 @@
  6.  FillChar(addr, SizeOf(addr), 0);
  7.  
  8. +{$ifdef openbsd}
  9. +addr.sin_len := SizeOf(addr);
  10. +{$endif}
  11. +
  12.  addr.sin_family := AF_INET;
  13.  addr.sin_port := htons(port);
  14.  


This apply for FPC 3.2.X

Thanks.

PS: i can not submit on gitlab.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Hello.
After, many tests, root cause identified:

OpenBSD sockaddr_in ABI requires:

* sin_len : byte
* sin_family : byte

Current RTL TInetSockAddr uses Linux-style layout:
sin_family : word

This shifts sockaddr fields and causes bind() to fail with errno 47 (EAFNOSUPPORT).

Adding packed record OpenBSD layout + sin_len initialization fixes fpBind().

this is a patch
Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/unix/sockets.pp b/rtl/unix/sockets.pp
  2. index XXXXXXX..YYYYYYY 100644
  3. --- a/rtl/unix/sockets.pp
  4. +++ b/rtl/unix/sockets.pp
  5. @@ -120,11 +120,20 @@ type
  6.    in_addr = record
  7.      s_addr : cuint32;
  8.    end;
  9.  
  10. +{$ifdef openbsd}
  11. +  TInetSockAddr = packed record
  12. +    sin_len    : byte;
  13. +    sin_family : byte;
  14. +    sin_port   : word;
  15. +    sin_addr   : in_addr;
  16. +    sin_zero   : array[0..7] of char;
  17. +  end;
  18. +{$else}
  19.    TInetSockAddr = packed record
  20.      sin_family : word;
  21.      sin_port   : word;
  22.      sin_addr   : in_addr;
  23.      sin_zero   : array[0..7] of char;
  24.    end;
  25. +{$endif}
  26.  


and

Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/unix/syssocket.inc b/rtl/unix/syssocket.inc
  2. index XXXXXXX..YYYYYYY 100644
  3. --- a/rtl/unix/syssocket.inc
  4. +++ b/rtl/unix/syssocket.inc
  5. @@ -45,6 +45,10 @@
  6.  FillChar(addr, SizeOf(addr), 0);
  7.  
  8. +{$ifdef openbsd}
  9. +addr.sin_len := SizeOf(addr);
  10. +{$endif}
  11. +
  12.  addr.sin_family := AF_INET;
  13.  addr.sin_port := htons(port);
  14.  


This apply for FPC 3.2.X

Thanks.

PS: i can not submit on gitlab.



I think that the correction exists on my FPC v: 3.2.4-rc1-d3a5f442 [2025/11/27]

Code: Pascal  [Select][+][-]
  1.   TInetSockAddr = sockaddr_in;
  2.   PInetSockAddr = psockaddr_in;
  3.  
  4.   psockaddr = ^sockaddr;
  5.   sockaddr = packed record // if sa_len is defined, sa_family_t is smaller
  6.   {$ifdef SOCK_HAS_SINLEN}
  7.      sa_len     : cuchar;
  8.   {$endif}
  9.     case integer of
  10.       0: (sa_family: sa_family_t;
  11.           sa_data: packed array[0..13] of cuint8);
  12.       1: (sin_family: sa_family_t;
  13.           sin_port: cushort;
  14.           sin_addr: in_addr;
  15.           sin_zero: packed array[0..7] of cuint8);
  16.   end;
  17.  
  18.   TSockAddr = sockaddr;
  19.  
I think we need just to define SOCK_HAS_SINLEN for BSD's systems while compiling packages.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12896
  • FPC developer.
Sockets.pp has

Code: Pascal  [Select][+][-]
  1. {$if
  2.      defined(FreeBSD) or
  3.      defined(Darwin) or
  4.      defined(Haiku)
  5. }
  6. {$DEFINE SOCK_HAS_SINLEN}               // BSD definition of socketaddr
  7. {$endif}
  8.  
[/code]

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Why it do not works then,
When I cross compile from Windows To OpenBSD, it fail on 'bind' and return Error 47.

I think we should add OpenBSD to defines.
« Last Edit: March 22, 2026, 09:37:37 pm by BSaidus »
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12896
  • FPC developer.
If you add it, does it work ? Then I'll commit it.

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
I'll give you feedback as soon I compile.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Yes, you can commit.

Code: Pascal  [Select][+][-]
  1.  
  2. {$if
  3.      defined(FreeBSD) or
  4.      defined(Darwin) or
  5.      defined(Haiku) or
  6.      defined(OpenBSD)
  7.  
  8. }
  9. {$DEFINE SOCK_HAS_SINLEN}               // BSD definition of socketaddr
  10. {$endif}
  11.  
  12.  


PS: Please, If you can, commit to branch 3.2.X also.
« Last Edit: March 22, 2026, 10:40:58 pm by BSaidus »
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

Fred vS

  • Hero Member
  • *****
  • Posts: 3942
    • StrumPract is the musicians best friend
this is a patch
Code: Pascal  [Select][+][-]
  1. diff --git a/rtl/unix/sockets.pp b/rtl/unix/sockets.pp
  2. ...
  3.  

Hello BSaidus.

I suppose that this patch is not for fpc 3.2.x because sockets.pp is in fpc/packages/rtl-extra/src/unix/sockets.pp.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
@Fred VS,
Yes Now it is in '.\fpcsrc\packages\rtl-extra\src\unix\',
I think I was mistake  :(.


lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

Fred vS

  • Hero Member
  • *****
  • Posts: 3942
    • StrumPract is the musicians best friend
Ha ok, thanks.

Other thing:
Quote
I think that the correction exists on my FPC v: 3.2.4-rc1-d3a5f442 [2025/11/27]

Hum, I dont see that commit in https://gitlab.com/freepascal.org/fpc/source/-/tree/release_3_2_4-branch/packages/rtl-extra/src/unix/sockets.pp.

Where do you get it?
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
Ha ok, thanks.

Other thing:
Quote
I think that the correction exists on my FPC v: 3.2.4-rc1-d3a5f442 [2025/11/27]

Hum, I dont see that commit in https://gitlab.com/freepascal.org/fpc/source/-/tree/release_3_2_4-branch/packages/rtl-extra/src/unix/sockets.pp.

Where do you get it?

I mean, the '$if defined' exists but without OpenBSD, so I added it & recompiled.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12896
  • FPC developer.
PS: Please, If you can, commit to branch 3.2.X also.

3.2.x is frozen in anticipation for 3.2.4 for already for an year. But I keep lists and if there are opportunities I'll try to merge.

p.s. if the openbsd pkg/ports system has a way to have OS specific patches over the release, this might be a candidate
« Last Edit: March 23, 2026, 09:55:06 am by marcov »

abouchez

  • Full Member
  • ***
  • Posts: 137
    • Synopse
I guess all this started with
https://github.com/synopse/mORMot2/issues/447

I have implemented a corresponding patch in mormot.net.sock.posix.inc:
https://github.com/synopse/mORMot2/commit/5a3540fd8

In fact, I re-defined all those records, and properly populate the sa_len field on BSD.
It seems that FreeBSD and Darwin allow sa_len = 0 and assume it means "this is the correct length".
But OpenBSD is more strict, and requires the proper length in bytes to be set in this sa_len field.

So
1) FPC needs to be patched to define SOCK_HAS_SINLEN conditional on OpenBSD
2) User code needs to populate the sa_len field properly

Both are now done automagically by the mORMot socket wrapper, which will work with old FPC versions - not only the trunk.
And by the way, I am currently preparing Delphi for Linux compiler support, so I needed those records definition anyway.

Fred vS

  • Hero Member
  • *****
  • Posts: 3942
    • StrumPract is the musicians best friend
I guess all this started with
https://github.com/synopse/mORMot2/issues/447

I have implemented a corresponding patch in mormot.net.sock.posix.inc:
https://github.com/synopse/mORMot2/commit/5a3540fd8

In fact, I re-defined all those records, and properly populate the sa_len field on BSD.
It seems that FreeBSD and Darwin allow sa_len = 0 and assume it means "this is the correct length".
But OpenBSD is more strict, and requires the proper length in bytes to be set in this sa_len field.

So
1) FPC needs to be patched to define SOCK_HAS_SINLEN conditional on OpenBSD
2) User code needs to populate the sa_len field properly

Both are now done automagically by the mORMot socket wrapper, which will work with old FPC versions - not only the trunk.
And by the way, I am currently preparing Delphi for Linux compiler support, so I needed those records definition anyway.

Note also that OpenBSD use a custom libc.so.xxx for each new release (unlike other Unix OS who use always libc.so.6).

So a fpc binary release is needed for each OpenBSD release.

You may use a fpc 3.2.4 release for OpenBSD 7.4, 7.5, 7.6, 7.7, 7.8 from here.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

BSaidus

  • Hero Member
  • *****
  • Posts: 666
  • lazarus 1.8.4 Win8.1 / cross FreeBSD
I guess all this started with
https://github.com/synopse/mORMot2/issues/447

I have implemented a corresponding patch in mormot.net.sock.posix.inc:
https://github.com/synopse/mORMot2/commit/5a3540fd8

In fact, I re-defined all those records, and properly populate the sa_len field on BSD.
It seems that FreeBSD and Darwin allow sa_len = 0 and assume it means "this is the correct length".
But OpenBSD is more strict, and requires the proper length in bytes to be set in this sa_len field.

So
1) FPC needs to be patched to define SOCK_HAS_SINLEN conditional on OpenBSD
2) User code needs to populate the sa_len field properly

Both are now done automagically by the mORMot socket wrapper, which will work with old FPC versions - not only the trunk.
And by the way, I am currently preparing Delphi for Linux compiler support, so I needed those records definition anyway.

Note also that OpenBSD use a custom libc.so.xxx for each new release (unlike other Unix OS who use always libc.so.6).

So a fpc binary release is needed for each OpenBSD release.

You may use a fpc 3.2.4 release for OpenBSD 7.4, 7.5, 7.6, 7.7, 7.8 from here.
Yep, but for me the code works & I create a symlink to libc as needed by the program.
lazarus 1.8.4 Win8.1 / cross FreeBSD
dhukmucmur vernadh!

 

TinyPortal © 2005-2018