You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Jakob Praher <ja...@dynatrace.com> on 2006/04/12 10:43:22 UTC
apr_socket_connect
hi all,
apparently I have a strange problem with apr_socket_connect, when
calling it several times within a short time period, it turns out to
return APR_SCUCESS without actually succeeded in connect( )ing!
After some research I found out, that on my machine (SUSE Linux 9.3,
uname=2.6.11.4-21.11-smp), the section of problem is the call to
getsockopt( ... SO_ERROR ... ) because:
after that:
- error is 0
- rc = 0
- errno is 115
normally error would not be 0 and therefore the block would exit with
if (error) {
return error;
}
but since it getsockopt( ) fills in &error with 0 the flow continues
past the next guard:
if (rc == -1 && errno != EISCONN) {
return errno;
}
and eventually returns APR_SUCCESS!!!
My question is:
Do you know if this is a bug in the SUSE maintained kernel. *Can*
getsockopt, according to its definition, behave like this, if connect( )
was not successful?
SOLUTION:
I would definitely keep the old rc when checking calling getsockopt.
This would lead to a more pessimistic error detection and would not
render apr_socket_connect( ) falsly returning APR_SUCCESS without a
connection as in my case!
For instance the following change:
1 : #ifdef SO_ERROR
2 : {
3 : int error;
4 : int rc_sockopt = rc;
5 : apr_socklen_t len = sizeof(error);
6 : if ((rc_sockopt = getsockopt(sock->socketdes,
7 : SOL_SOCKET, SO_ERROR,
8 : (char *)&error, &len)) < 0) {
9 : return errno;
10: }
11: if (error) {
12: return error;
13: }
14: }
15: #endif /* SO_ERROR */
line 4,5 use a rc_sockopt instead of overwriting the outer rc. This
would leave the final check to return the errno,
if (rc == -1 && errno != EISCONN) {
return errno;
}
thanks in advance
-- Jakob
Re: apr_socket_connect
Posted by Jakob Praher <ja...@dynatrace.com>.
hi jeff,
Jeff Trawick wrote:
> On 4/12/06, Jakob Praher <ja...@dynatrace.com> wrote:
>>hi all,
>>
>>apparently I have a strange problem with apr_socket_connect, when
>>calling it several times within a short time period, it turns out to
>>return APR_SCUCESS without actually succeeded in connect( )ing!
>
> What socket options have you set on the socket? timeout or just non-blocking?
blocking with timeout, the following settings apply:
apr_socket_opt_set(mpSocket, APR_TCP_NODELAY, 1);
apr_socket_timeout_set(mpSocket, 30*1000000LL );
everything else is as is.
>
> If you set it to non-blocking, did you wait for the APR_POLLOUT
> condition with apr_poll() on the socket before calling
> apr_socket_connect again? I think the error from getsockopt() is
> reset once it is retrieved the first time. That may be the issue
> triggered with calling apr_socket_connect() multiple times.
>
see above. it is a vanilla blocking socket.
> I wouldn't suspect a bug in the kernel for this, or many applications
> would fail.
>
it is interesting though.
it boils really down to that, it is due to getsockopt.
--
Jakob
Re: apr_socket_connect
Posted by Jeff Trawick <tr...@gmail.com>.
On 4/12/06, Jakob Praher <ja...@dynatrace.com> wrote:
> hi all,
>
> apparently I have a strange problem with apr_socket_connect, when
> calling it several times within a short time period, it turns out to
> return APR_SCUCESS without actually succeeded in connect( )ing!
What socket options have you set on the socket? timeout or just non-blocking?
If you set it to non-blocking, did you wait for the APR_POLLOUT
condition with apr_poll() on the socket before calling
apr_socket_connect again? I think the error from getsockopt() is
reset once it is retrieved the first time. That may be the issue
triggered with calling apr_socket_connect() multiple times.
I wouldn't suspect a bug in the kernel for this, or many applications
would fail.