Comments (10)
Let's introduce a breaking change:
peekSocketAddress :: Ptr sa -> Int -> IO sa
And let's release it with a new major version.
from network.
@Philonous As you think, SockAddrUnix ""
would be the best workaround.
Would you kindly send a PR?
from network.
@Philonous Gentle ping.
from network.
I'm working on it. This isn't as obvious as I first thought.
- Since 3.0
Socket
doesn't container the address family any more, so I can't check it to return the correct address type whenaddrlen
is 0. - I'm thinking that just returning
SockAddrUnix ""
wheneveraddrlen
is 0 regardless of the socket type might work, it's at least not worse than the situation before.
However, there's another problem:
network/Network/Socket/Types.hsc
Line 1192 in 09f30fa
is incorrect:
- POSIX doesn't specify that
sun_path
is null-terminated (though at least on Linux and *BSD apparently it is) - On Linux, the terminating null byte can sometimes be truncated [1] even for correctly sized buffers (
sizeof(sockaddr_un)
)- This doesn't affect the existing code because it allocates and zeroes
sizeof(sockaddr_storage) = 128 bytes
[2][3], so there's always a null byte aftersun_path
. ButSocketAddress
' is publicly exported and can be implemented for a new type, e.g. one that passes a buffer of sizesizeof(sockaddr_un) bytes
, which should work.
- This doesn't affect the existing code because it allocates and zeroes
- Abstract paths can contain null characters, so the only way to handle them properly is to know the length of
sun_path
- This is handled correctly in other places[4], so it's surprising that
peekSocketAddress
completely fails
- This is handled correctly in other places[4], so it's surprising that
As far as I can see, the interface peekSocketAddress :: Ptr sa -> IO sa
can't work, because it needs addrlen
to correctly decode sockaddr_un
. It might also be a good idea to handle the case where addlen = 0
there.
- [1] https://man7.org/linux/man-pages/man7/unix.7.html see section BUGS:
However, there is one
case where confusing behavior can result: if 108 non-null bytes
are supplied when a socket is bound, then the addition of the
null terminator takes the length of the pathname beyond
sizeof(sun_path). Consequently, when retrieving the socket
address (for example, via accept(2)), if the input addrlen
argument for the retrieving call is specified as sizeof(struct
sockaddr_un), then the returned address structure won't have a
null terminator in sun_path.
- [2]
network/Network/Socket/Types.hsc
Lines 1021 to 1023 in 09f30fa
- [3]
network/Network/Socket/Types.hsc
Line 1010 in 09f30fa
- [4]
network/Network/Socket/Types.hsc
Lines 1114 to 1117 in 09f30fa
from network.
Since 3.0 Socket doesn't container the address family any more, so I can't check it to return the correct address type when addrlen is 0.
Why don't you use getSocketName
to get its SocketAddress
type?
from network.
As far as I can see, the interface peekSocketAddress :: Ptr sa -> IO sa can't work, because it needs addrlen to correctly decode sockaddr_un. It might also be a good idea to handle the case where addlen = 0 there.
Can't we use sizeOfSocketAddress
or sizeOfSockAddr
to get addrlen
?
from network.
Why don't you use getSocketName to get its SocketAddress type?
- AFAIK Windows doesn't allow
getsocketname()
on unbound sockets. [1] Windows doesn't haveAF_UNIX
either, so the code could be conditionally included. - POSIX explicitly mentions that
getsocketname()
on unbound sockets returns unspecified data [2]. Although on Linux it seems to at least return the correct address family.
Can't we use sizeOfSocketAddress or sizeOfSockAddr to get addrlen?
We already have addrlen
, recvfrom()
etc. are passing it back to us. The problem is that we need it inside peekSocketAddress
to correctly decode sockaddr_un
.
sizeOfSocketAddress
needs an already decoded address, so we can't use it inside peekSocketAddress
.
WSAEINVAL | The socket has not been bound to an address with bind, or ADDR_ANY is specified in bind but connection has not yet occurred.
If the socket has not been bound to a local name, the value stored in the object pointed to by address is unspecified.
from network.
I've been working on this, but I've been stuck on
network/Network/Socket/Buffer.hsc
Line 125 in 26e9d3c
I think the idea here is that for connected sockets, recvfrom()
and recvmsg()
don't return the remote address, so the getpeername()
is there for convenience.
This assumes that recvfrom()
will only not return an address when the socket is connected, which is false for AF_UNIX
(this is what this ticket is about in the first place). In general, this would be false whenever we receive a packet from an unnamed socket. So I've been trying to figure out if this can happen besides with AF_UNIX
. It could in theory happen with socketpair()
, but none of the platforms I checked (Linux, FreeBSD, OpenBSD, NetBSD, Solaris) support socketpair()
with anything but AF_UNIX
, windows doesn't have socketpair()
.
Next I tried to figure out if getsockname()
is guaranteed to return sensible data even for unbound sockets at least on *nix, since POSIX specifically states that it is "unspecified". On Windows it seems to be forbidden anyway, so it would have to be #ifdef
-ed out. Linux just returns an empty address, which is fine, FreeBSD returns the correct address family and a bunch of garbage, but it looked like it should at least be safe to read, but I'm not entirely certain. I did not check on the other platforms for lack of time and easy access
I think this is brittle. A slightly better idea (in my opinion) might be to store the address family in the Socket
value like before 3.0.
But I think the morally correct approach would be to change recvFrom
's etc type signature from
recvFrom :: SocketAddress sa => Socket -> Int -> IO (ByteString, sa)
to
recvFrom :: SocketAddress sa => Socket -> Int -> IO (ByteString, Maybe sa)
and remove the call to getpeername()
.
It would remove the possibility of failure and more closely resemble the the underlying API.
Unfortunately, it would be a breaking change and presumably affect a lot of existing code.
from network.
I would suggest to keep recvFrom
as is and provide a new safeRecvFrom
which satisfies you.
from network.
Related Issues (20)
- Releasing 3.1.2.3 HOT 1
- Edited: network-3.1.2.3 doesn't compile on Windows with cabal 3.4.0 HOT 9
- network-3.1.2.5 not building on MacOS Big Sur HOT 6
- IP_PKTINFO HOT 2
- Does sendAll really throw exception on error? HOT 6
- network-3.1.2.6 does not compile on windows (again) HOT 9
- add SOCKS5-hostname proxy HOT 3
- Add MSG_DONTWAIT MessageFlag (or "how to detect if the connection is closed by the client") HOT 4
- Cannot install 3.1.1.1 on Windows
- custom nix version HOT 1
- Failed to build network-3.1.2.7 with ghc-8.10 on Linux HOT 1
- Will not build without msghdr.msg_control HOT 3
- Sending data and file descriptors at the same time HOT 7
- SendTimeOut/RecvTimeOut
- Problems building with network dependency on Windows (GHC 9.6.1/Cabal 3.10.1.0) HOT 12
- Document how to close sockets in a threaded scenario HOT 7
- Support GHCs 9.4 and 9.6 in CI HOT 1
- Emulating socketPair on Windows HOT 7
- Don't declare `_GNU_SOURCE` on Windows HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from network.