snapframework / io-streams-haproxy

HAProxy protocol v1.5 support for io-streams
BSD 3-Clause "New" or "Revised" License
7 stars 17 forks source link

getPeerName: invalid argument (Transport endpoint is not connected) #2

Closed hvr closed 9 years ago

hvr commented 10 years ago

I'm using code like the following, which causes problems with haproxys default keepalive check which consists in sending a PROXY header and closing the connection right ahead:

(s,sa) <- accept sock
(inst,outst) <- socketToStreams s
localPInfo <- socketToProxyInfo s

The problem is that by the time getPeerName is called, the connection is already closed, so the system calls fails.

However, if I there was a function which allowed me to pass in the sa I already got from the accept, i.e.

socketToProxyInfo :: N.Socket -> IO ProxyInfo
socketToProxyInfo s = socketToProxyInfoWithPeerName s =<< N.getPeerName s

socketToProxyInfoWithPeerName :: N.Socket -> N.SockAddr -> IO ProxyInfo
socketToProxyInfoWithPeerName s sa = do
    da <- N.getSocketName s
    let (N.MkSocket _ _ !sty _ _) = s
    return $! makeProxyInfo sa da (addrFamily sa) sty

I can write the code like below and avoid calling getPeerName (and thus avoid the failure):

(s,sa) <- accept sock
(inst,outst) <- socketToStreams s
localPInfo <- socketToProxyInfoWithPeerName s sa
gregorycollins commented 10 years ago

Hey Herbert, what is the status on this? Do you think you know what the right fix is?

hvr commented 10 years ago

I'd say this this an API design question.

I don't see a way around changing the API to be able to use the sa information returned by (s,sa) <- accept sock instead of (redundantly) calling getPeerName again on the s which may have been closed by then already.

gregorycollins commented 10 years ago

It's not released on hackage yet, so we can go ahead and change it. Do you want to have a stab at fixing it? Otherwise I'll add it to my queue :)

gregorycollins commented 9 years ago

OK, I'm about to fix this, but I'll have to ask you to test it. I'm worried the call to getSocketName is going to cause the same issue.