Professional Web Applications Themes

Timeout for connect() - UNIX Programming

How does one find out the timeout value on the connect() function? I know the value is set at the pleasure of the system, so how do I find out what it is? Also, I've heard that you can use SIGALARM (with the help of alarm()) to cancel a blocking function like connect(), but what I don't quite get is how to use the handle. I've read that I need to write a handler for SIGALARM, but how does such a handler affect connect()? I've also read that I set the handler to SIG_IGN. I don't believe everything I read....

  1. #1

    Default Timeout for connect()

    How does one find out the timeout value on the connect() function? I
    know the value is set at the pleasure of the system, so how do I find
    out what it is?
    Also, I've heard that you can use SIGALARM (with the help of
    alarm()) to cancel a blocking function like connect(), but what I
    don't quite get is how to use the handle. I've read that I need to
    write a handler for SIGALARM, but how does such a handler affect
    connect()? I've also read that I set the handler to SIG_IGN. I don't
    believe everything I read.
    Jo Guest

  2. #2

    Default Re: Timeout for connect()


    "Jo" <com> wrote in message
    news:google.com...

     

    There is no timeout value on the 'connect' function. The 'connect' takes
    an amount of time that depends upon numerous factors, none of which are
    really the application's business except in very unusual cirstances.
     

    You can't. It could depend upon any number of factors that you don't
    know. Why do you think you need to know this?

     

    You can set the handler to SIG_IGN. The signal will be ignored, but it
    will cause 'connect' to return before the connection completes or fails. The
    connection will still be in process when 'connect' returns EINTR. You can
    call 'connect' later to find if it sucfeeded or fail.

    DS



    David Guest

  3. #3

    Default Re: Timeout for connect()

    Jo wrote: 

    Another way of controlling the time connect() takes is to
    use non-blocking connects. Set the socket file descriptor
    to non-blocking, select() or poll() on it afterwards
    (Stevens' book "Unix Network Programming" has code examples).

    Some systems (e.g. Solaris, maybe HP-UX) have a TCP parameter
    TCP_CONN_ABORT_THRESHOLD that can be set:

    #ifdef TCP_CONN_ABORT_THRESHOLD
    /* defined in <netinet/tcp.h>

    /* Solaris provides a way to set a timeout for outbound
    * TCP connections.
    */
    {
    unsigned time_ms;
    int len = sizeof (time_ms);

    if ( getsockopt(serverfd, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD,
    (char *)&time_ms, &len) == -1 ) {
    perror ("getsockopt TCP_CONN_ABORT_THRESHOLD");
    } else {
    fprintf (stderr, "DEBUG: default connect time is %d\n", time_ms);
    }

    time_ms = TCP_CONN_TIMEOUT * 1000;

    fprintf (stderr, "DEBUG: setting connect time to %d\n", time_ms);
    if ( setsockopt(serverfd, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD,
    (char *)&time_ms, sizeof (time_ms)) == -1 ) {
    perror ("setsockopt TCP_CONN_ABORT_THRESHOLD");
    }
    }
    #endif

    Heiner
    --
    ___ _
    / __| |_ _____ _____ _ _ Heiner STEVEN <de>
    \__ \ _/ -_) V / -_) ' \ Shell Script Programmers: visit
    |___/\__\___|\_/\___|_||_| http://www.shelldorado.com/
    Heiner Guest

  4. #4

    Default Re: Timeout for connect()

    "David Schwartz" <com> wrote in message news:<c1ref7$i1j$webmaster.com>... 
    >
    > There is no timeout value on the 'connect' function. The 'connect' takes
    > an amount of time that depends upon numerous factors, none of which are
    > really the application's business except in very unusual cirstances.

    >
    > You can't. It could depend upon any number of factors that you don't
    > know. Why do you think you need to know this?[/ref]

    Because I would want to know the maximum amount of time connect()
    would block for.
     
    >
    > You can set the handler to SIG_IGN. The signal will be ignored, but it
    > will cause 'connect' to return before the connection completes or fails. The
    > connection will still be in process when 'connect' returns EINTR. You can
    > call 'connect' later to find if it sucfeeded or fail.[/ref]

    Oh yeah? Don't I run the risk of some kind of leak? Say, a
    connection or socket leak? I'm also a bit surprised at how simple it
    would be to write non-blocking code. I avoided the solution that
    involves select(), because it was too complicated for my
    implementation. From what I'm hearing here, I could do something like
    this:

    do {
    alarm(1);
    } while (connect(who, &cares, question_mark) == -1 && errno == EINTR);
    alarm(0);

    Each call to connect() here will go back to the first call's
    connection context and not create a new one? If that's so, why does
    the solution to a non-blocking connect() in the faq have that
    complicated code involving a select()?
    Jo Guest

  5. #5

    Default Re: Timeout for connect()


    "Jo" <com> wrote in message
    news:google.com...

     [/ref]
     


    There is no way to know. In general, an application has no way to know
    how long a network protocol will take to complete a task or fail at it.
     
    >>
    >> You can set the handler to SIG_IGN. The signal will be ignored, but
    >> it
    >> will cause 'connect' to return before the connection completes or fails.
    >> The
    >> connection will still be in process when 'connect' returns EINTR. You can
    >> call 'connect' later to find if it sucfeeded or fail.[/ref]
    >
    > Oh yeah? Don't I run the risk of some kind of leak? Say, a
    > connection or socket leak?[/ref]

    I'm not sure what you're talking about. You only run the risk of a leak
    if you don't close the things you open.
     


    Just don't forget to ignore SIG_ALARM. I think you have this wrong
    though. The second call to 'connect' will fail with EINPROGRESS.

     

    You have your code wrong. Your second call to 'connect' will fail
    immediately because a connection is already in progress.

    Can you state your actual problem? Odds are the solution has nothing
    whatsoever to do with connection timeouts. What's the problem you have? What
    are you trying to do?

    DS




    David Guest

  6. #6

    Default Re: Timeout for connect()

    "David Schwartz" <com> wrote in message news:<c1u4go$6vc$webmaster.com>... 
    > >
    > > Oh yeah? Don't I run the risk of some kind of leak? Say, a
    > > connection or socket leak?[/ref]
    >
    > I'm not sure what you're talking about. You only run the risk of a leak
    > if you don't close the things you open.[/ref]

    That's what I was thinking of. Is there any danger in closing a
    socket that hasn't been opened? If not, then I would think the proper
    solution would be to close the socket once you know that the connect
    is to be canceled.
     
    >
    >
    > Just don't forget to ignore SIG_ALARM. I think you have this wrong
    > though. The second call to 'connect' will fail with EINPROGRESS.[/ref]

    Alright, how 'bout this then:
    signal(SIGALARM,SIG_IGN);
    do {
    alarm(1);
    } while (connect(who, &cares, question_mark) == -1 && (errno==EINTR ||
    errno==EINPROGRESS);
     
    >
    > You have your code wrong. Your second call to 'connect' will fail
    > immediately because a connection is already in progress.
    >
    > Can you state your actual problem? Odds are the solution has nothing
    > whatsoever to do with connection timeouts. What's the problem you have? What
    > are you trying to do?[/ref]

    I'm writing a daemon, so I wanted to be able to cancel the connect
    on SIGTERM, or at least know for how long the connect() would block so
    the daemon-shutdown routine would know how long to wait. I also want
    to put a cap on the timeout of the connect(). In either situtation, I
    need to leave the connect() to see if it is supposed to cancel. If it
    is supposed to cancel, I need to free any allocated resources. But if
    it's not supposed to cancel, I need to monitor the status of the
    connect(). Everywhere else I've read recommends using a complicated
    select() routine. Why is this routine so simple?
    Jo Guest

  7. #7

    Default Re: Timeout for connect()

    In article <google.com>,
    com (Jo) wrote:
     

    Once you create the socket using socket(), you *must* close it when
    you're not interested in using it any more. I guess what you meant was
    "is there any danger in closing a socket whose *connection* hasn't been
    opened?" No, there isn't -- listening sockets don't have open
    connections and it's fine to close them.

    --
    Barry Margolin, mit.edu
    Arlington, MA
    *** PLEASE post questions in newsgroups, not directly to me ***
    Barry Guest

  8. #8

    Default Re: Timeout for connect()


    "Jo" <com> wrote in message
    news:google.com...

     


    There is no such thing as "a socket that hasn't been opened". The open
    ('socket') operation creates the socket and the close ('close') function
    destroys it. If you have it, it's open.
     
    >
    > Alright, how 'bout this then:
    > signal(SIGALARM,SIG_IGN);
    > do {
    > alarm(1);
    > } while (connect(who, &cares, question_mark) == -1 && (errno==EINTR ||
    > errno==EINPROGRESS);[/ref]


    The problem is that this will spin and burn the CPU. Each call to
    'connect' (except the first) will fail immediately with EINPROGRESS. You
    could put in a short sleep if you get back EINPROGRESS, but then you may
    waste some time after the connection completes. This is what 'poll' or
    'select' is for.

     [/ref]
     

    Wait until the connect fails!
     

    I don't follow you here. If you initiated the 'connect', wait until it
    finishes. If you decide to shutdown after the 'connect' attempt, either
    abort the 'connect' right then or wait until it finishes. I don't see where
    you need to know how long 'connect' might or might not take.

    DS




    David Guest

  9. #9

    Default Re: Timeout for connect()

    "David Schwartz" <com> wrote in message news:<c20di3$hmb$webmaster.com>... 
    >
    >
    > There is no such thing as "a socket that hasn't been opened". The open
    > ('socket') operation creates the socket and the close ('close') function
    > destroys it. If you have it, it's open.

    > >
    > > Alright, how 'bout this then:
    > > signal(SIGALARM,SIG_IGN);
    > > do {
    > > alarm(1);
    > > } while (connect(who, &cares, question_mark) == -1 && (errno==EINTR ||
    > > errno==EINPROGRESS);[/ref]
    >
    >
    > The problem is that this will spin and burn the CPU. Each call to
    > 'connect' (except the first) will fail immediately with EINPROGRESS. You
    > could put in a short sleep if you get back EINPROGRESS, but then you may
    > waste some time after the connection completes. This is what 'poll' or
    > 'select' is for.[/ref]

    I gather from what you are saying that only the first call to
    connect will block. After the alarm goes, any further call to connect
    will be non-blocking? As for wasting time after the connection
    completes; I think I can wait 100ms, even more: 10ms.
     [/ref]

    >
    > Wait until the connect fails![/ref]

    Oh, well, if I have to wait for the connect to fail, then there's
    no point. That's what my code is doing now, w/out any of this
    non-blocking or SIGALARM.
     
    >
    > I don't follow you here. If you initiated the 'connect', wait until it
    > finishes. If you decide to shutdown after the 'connect' attempt, either
    > abort the 'connect' right then or wait until it finishes. I don't see where
    > you need to know how long 'connect' might or might not take.[/ref]

    When the call to the daemon issues a shutdown, it sends a SIGTERM
    to the child--the process doing the connect. The sender then waits for
    the process to exit. If the sender knows how long a timeout would be,
    then the sender would know for how long to wait. Now if the connect
    has taken as long as I want the timeout to be, what can I do about it?
    You sounded like you were getting to that when you said "abort".
    Jo Guest

  10. #10

    Default Re: Timeout for connect()


    "Jo" <com> wrote in message
    news:google.com... [/ref]
     

    The 'connect' function attempts to initiate a connection. If one is
    already in progress, it will fail immediately. So you should only call
    'connect' once on a socket.
     


    Then you can do a loop with a sleep in each pass if you want.

     
    >>
    >> Wait until the connect fails![/ref]
    >
    > Oh, well, if I have to wait for the connect to fail, then there's
    > no point. That's what my code is doing now, w/out any of this
    > non-blocking or SIGALARM.[/ref]


    Why do you say there's no point. That seems to make sense to me. Either
    wait for the connect to fail or abort it immediately.

     [/ref]
     

    When the child process receives a signal, it will normally interrupt the
    'connect' anyway. I'm having a hard time figuring out why you don't just do
    things the easy way. Arrange the shutdown indication to interrupt the
    'connect' and when you get EINTR, you'll know it's time to shut down.

    DS




    David Guest

  11. #11

    Default Re: Timeout for connect()

    "David Schwartz" <com> wrote in message news:<c216si$107$webmaster.com>... [/ref]

    >
    > The 'connect' function attempts to initiate a connection. If one is
    > already in progress, it will fail immediately. So you should only call
    > 'connect' once on a socket.

    >
    >
    > Then you can do a loop with a sleep in each pass if you want.[/ref]

    But you just said I shouldn't call connect more than once. How do I
    detect the success of this connection in the loop if not with a call
    to connect? I'd rather not use the select solution, because it
    requires a read or a write to detect the success.

    But why do I need to loop at all? What if I just set the alarm to
    my timeout time, and if connect returns an EINTR, I know to quit the
    program? I would have done this before, but you said to wait for the
    connect to fail, and I still don't know how to "abort" the connection.
    Jo Guest

  12. #12

    Default Re: Timeout for connect()


    "Jo" <com> wrote in message
    news:google.com...

     [/ref]
     


    You could call 'connect' in the loop to see what error you get so long
    as there is a sleep in the loop, you won't burn the CPU. You can also use
    'getsockopt(SO_ERROR)' or set the socket non-blocking and wait until it's
    ready for writing.

     

    The problem is, what if the alarm fires and you have no interest in
    shutting down?

    DS



    David Guest

  13. #13

    Default Re: Timeout for connect()

    On 2 Mar 2004 07:12:52 -0800, com (Jo) wrote:
     

    I've been waiting for an explanation of this, also.

    David, do you mean just closing the socket?

    --
    Al Balmer
    Balmer Consulting
    net
    Alan Guest

Similar Threads

  1. Replies: 3
    Last Post: October 11th, 06:16 PM
  2. Replies: 5
    Last Post: July 15th, 08:52 PM
  3. #40517 [NEW]: async connections do not obey connect timeout
    By djgrrr+phpbugs at p2p-network dot net in forum PHP Bugs
    Replies: 2
    Last Post: February 19th, 01:18 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139