Quantcast

Peername of a closed TCP socket

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Peername of a closed TCP socket

Malcolm Dowse
Hello,

When a TCP client disconnects very soon after connecting to an Erlang server, is there any reliable way of getting the client's remote address?

The inet:peername/1 function returns an error if the socket in question has closed. As a result, I can't find any better solution than to refactor the code so that inet:peername/1 is called as soon as possible after the gen_tcp:accept/1.

Thanks in advance,

malcolm

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Peername of a closed TCP socket

Tony Rogvall-2
You can try the inet option:
        {exit_on_close, false}
This will keep the port and the socket active so you can read  
statistics,
continue write data to a half open socket and possibly get the  
peername, if that is available
by the underlying operating system.

You must then call gen_tcp:close to terminate the port/socket

/Tony


On 26 maj 2009, at 17.39, Malcolm Dowse wrote:

> Hello,
>
> When a TCP client disconnects very soon after connecting to an  
> Erlang server, is there any reliable way of getting the client's  
> remote address?
>
> The inet:peername/1 function returns an error if the socket in  
> question has closed. As a result, I can't find any better solution  
> than to refactor the code so that inet:peername/1 is called as soon  
> as possible after the gen_tcp:accept/1.
>
> Thanks in advance,
>
> malcolm
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://www.erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://www.erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Peername of a closed TCP socket

Malcolm Dowse
Hi,

Thanks for the tip, but unfortunately it didn't help. After some more
investigation I managed to reproduce the issue. The client was closing
its connection immediately after opening with the SO_LINGER option
enabled, and a timeout of 0 seconds. This resulted in a RST with no FIN.
So, even if I called peername immediately after accept, with option
{exit_on_close, false} set, it always returned enotconn.

However, when I wrote a server in C I had no problem getting the remote
address. The 'accept' C call returns a socket address along with the new
file descriptor. This is also the interface given by the 'accept' call
in python's socket module.

Would it be possible to get a similar accept interface in Erlang, in the
future?

best regards,

malcolm

-----Original Message-----
From: Tony Rogvall [mailto:[hidden email]]
Sent: 26 May 2009 22:06
To: Dowse, Malcolm
Cc: Erlang Questions
Subject: Re: [erlang-questions] Peername of a closed TCP socket

You can try the inet option:
        {exit_on_close, false}
This will keep the port and the socket active so you can read  
statistics,
continue write data to a half open socket and possibly get the  
peername, if that is available
by the underlying operating system.

You must then call gen_tcp:close to terminate the port/socket

/Tony


On 26 maj 2009, at 17.39, Malcolm Dowse wrote:

> Hello,
>
> When a TCP client disconnects very soon after connecting to an  
> Erlang server, is there any reliable way of getting the client's  
> remote address?
>
> The inet:peername/1 function returns an error if the socket in  
> question has closed. As a result, I can't find any better solution  
> than to refactor the code so that inet:peername/1 is called as soon  
> as possible after the gen_tcp:accept/1.
>
> Thanks in advance,
>
> malcolm
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://www.erlang.org/mailman/listinfo/erlang-questions


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Peername of a closed TCP socket

Tony Rogvall-2
Sad to hear that it did not work. So I checked the code.
The peername is already stored away in a field called inet.remote  in  
the driver.
The call to get the peername do not use that field, instead it calls  
getpeername
which of course will fail in your case.

A simple fix (tm) will be to change the inet_drv to return the  
inet.remote when possible
instead of calling getpeername. There is some code to set fake  
peernames (used
by old socks/proxy implemenation) that needs to be handled, otherwise  
I do not see any problems.

OTP?

/Tony


On 3 jun 2009, at 13.19, Dowse, Malcolm wrote:

> Hi,
>
> Thanks for the tip, but unfortunately it didn't help. After some more
> investigation I managed to reproduce the issue. The client was closing
> its connection immediately after opening with the SO_LINGER option
> enabled, and a timeout of 0 seconds. This resulted in a RST with no  
> FIN.
> So, even if I called peername immediately after accept, with option
> {exit_on_close, false} set, it always returned enotconn.
>
> However, when I wrote a server in C I had no problem getting the  
> remote
> address. The 'accept' C call returns a socket address along with the  
> new
> file descriptor. This is also the interface given by the 'accept' call
> in python's socket module.
>
> Would it be possible to get a similar accept interface in Erlang, in  
> the
> future?
>
> best regards,
>
> malcolm
>
> -----Original Message-----
> From: Tony Rogvall [mailto:[hidden email]]
> Sent: 26 May 2009 22:06
> To: Dowse, Malcolm
> Cc: Erlang Questions
> Subject: Re: [erlang-questions] Peername of a closed TCP socket
>
> You can try the inet option:
> {exit_on_close, false}
> This will keep the port and the socket active so you can read
> statistics,
> continue write data to a half open socket and possibly get the
> peername, if that is available
> by the underlying operating system.
>
> You must then call gen_tcp:close to terminate the port/socket
>
> /Tony
>
>
> On 26 maj 2009, at 17.39, Malcolm Dowse wrote:
>
>> Hello,
>>
>> When a TCP client disconnects very soon after connecting to an
>> Erlang server, is there any reliable way of getting the client's
>> remote address?
>>
>> The inet:peername/1 function returns an error if the socket in
>> question has closed. As a result, I can't find any better solution
>> than to refactor the code so that inet:peername/1 is called as soon
>> as possible after the gen_tcp:accept/1.
>>
>> Thanks in advance,
>>
>> malcolm
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Peername of a closed TCP socket

Cameron Kerr-2
In reply to this post by Malcolm Dowse
In your C server, what happens if you put a sleep(1) between the  
accept(socket, NULL, ...) and the getpeername()?

I'm [still a relative Erlang newbie, but an experienced socket  
programmer] thinking it's basically a race condition. What you really  
want in this case is the form of accept(2) that gives you the  
peername. That way this case cannot occur. Unfortunately, there is no  
suitable inet:accept variant that gives you this information, as far  
as I can tell. (Would love to be corrected about that).

On 3/06/2009, at 11:19 PM, Dowse, Malcolm wrote:

> Hi,
>
> Thanks for the tip, but unfortunately it didn't help. After some more
> investigation I managed to reproduce the issue. The client was closing
> its connection immediately after opening with the SO_LINGER option
> enabled, and a timeout of 0 seconds. This resulted in a RST with no  
> FIN.
> So, even if I called peername immediately after accept, with option
> {exit_on_close, false} set, it always returned enotconn.
>
> However, when I wrote a server in C I had no problem getting the  
> remote
> address. The 'accept' C call returns a socket address along with the  
> new
> file descriptor. This is also the interface given by the 'accept' call
> in python's socket module.
>
> Would it be possible to get a similar accept interface in Erlang, in  
> the
> future?
>
> best regards,
>
> malcolm
>
> -----Original Message-----
> From: Tony Rogvall [mailto:[hidden email]]
> Sent: 26 May 2009 22:06
> To: Dowse, Malcolm
> Cc: Erlang Questions
> Subject: Re: [erlang-questions] Peername of a closed TCP socket
>
> You can try the inet option:
> {exit_on_close, false}
> This will keep the port and the socket active so you can read
> statistics,
> continue write data to a half open socket and possibly get the
> peername, if that is available
> by the underlying operating system.
>
> You must then call gen_tcp:close to terminate the port/socket
>
> /Tony
>
>
> On 26 maj 2009, at 17.39, Malcolm Dowse wrote:
>
>> Hello,
>>
>> When a TCP client disconnects very soon after connecting to an
>> Erlang server, is there any reliable way of getting the client's
>> remote address?
>>
>> The inet:peername/1 function returns an error if the socket in
>> question has closed. As a result, I can't find any better solution
>> than to refactor the code so that inet:peername/1 is called as soon
>> as possible after the gen_tcp:accept/1.
>>
>> Thanks in advance,
>>
>> malcolm
>> _______________________________________________
>> erlang-questions mailing list
>> [hidden email]
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Peername of a closed TCP socket

Cameron Kerr-2
Sorry, I had misread your question; my response contains little of  
value.

On 4/06/2009, at 6:08 AM, Cameron Kerr wrote:

> In your C server, what happens if you put a sleep(1) between the  
> accept(socket, NULL, ...) and the getpeername()?
>
> I'm [still a relative Erlang newbie, but an experienced socket  
> programmer] thinking it's basically a race condition. What you  
> really want in this case is the form of accept(2) that gives you the  
> peername. That way this case cannot occur. Unfortunately, there is  
> no suitable inet:accept variant that gives you this information, as  
> far as I can tell. (Would love to be corrected about that).
>
> On 3/06/2009, at 11:19 PM, Dowse, Malcolm wrote:
>
>> Hi,
>>
>> Thanks for the tip, but unfortunately it didn't help. After some more
>> investigation I managed to reproduce the issue. The client was  
>> closing
>> its connection immediately after opening with the SO_LINGER option
>> enabled, and a timeout of 0 seconds. This resulted in a RST with no  
>> FIN.
>> So, even if I called peername immediately after accept, with option
>> {exit_on_close, false} set, it always returned enotconn.
>>
>> However, when I wrote a server in C I had no problem getting the  
>> remote
>> address. The 'accept' C call returns a socket address along with  
>> the new
>> file descriptor. This is also the interface given by the 'accept'  
>> call
>> in python's socket module.
>>
>> Would it be possible to get a similar accept interface in Erlang,  
>> in the
>> future?
>>
>> best regards,
>>
>> malcolm
>>
>> -----Original Message-----
>> From: Tony Rogvall [mailto:[hidden email]]
>> Sent: 26 May 2009 22:06
>> To: Dowse, Malcolm
>> Cc: Erlang Questions
>> Subject: Re: [erlang-questions] Peername of a closed TCP socket
>>
>> You can try the inet option:
>> {exit_on_close, false}
>> This will keep the port and the socket active so you can read
>> statistics,
>> continue write data to a half open socket and possibly get the
>> peername, if that is available
>> by the underlying operating system.
>>
>> You must then call gen_tcp:close to terminate the port/socket
>>
>> /Tony
>>
>>
>> On 26 maj 2009, at 17.39, Malcolm Dowse wrote:
>>
>>> Hello,
>>>
>>> When a TCP client disconnects very soon after connecting to an
>>> Erlang server, is there any reliable way of getting the client's
>>> remote address?
>>>
>>> The inet:peername/1 function returns an error if the socket in
>>> question has closed. As a result, I can't find any better solution
>>> than to refactor the code so that inet:peername/1 is called as soon
>>> as possible after the gen_tcp:accept/1.
>>>
>>> Thanks in advance,
>>>
>>> malcolm
>>> _______________________________________________
>>> erlang-questions mailing list
>>> [hidden email]
>>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>
>>
>> ________________________________________________________________
>> erlang-questions mailing list. See http://www.erlang.org/faq.html
>> erlang-questions (at) erlang.org
>>
>>
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Loading...