SIGALRM not working for connect call to unresponsive system

Discussion in 'Linux Networking' started by kenakahn, Nov 7, 2012.

  1. kenakahn

    kenakahn Guest

    I have the following code segment set up to simulate a timeout for a connect()

    signal(SIGALRM,Timed_Out);
    alarm(Response_timeout);

    if (connect(socket_hdl,(struct sockaddr *)&sin,sizeof(sin)) == -1) { printf("ERROR: Could not connect to server (rc=%d):
    %s\n",errno,strerror(errno));
    close(socket_hdl);
    return 0;
    }

    void Timed_Out(int signum) {
    signal(SIGPROF,SIG_IGN);
    printf("ERROR: Connection to configmgr host failed\n");
    exit(0);
    }

    This works in 99% if the cases where the connect fails to occur withing the specified timeout.

    However, we have a system that is 'sick'; it responses to pings but nothing else we've tried; i.e. telnet rlogin rsh

    We're expecting the connect to fail and the SIGALRM to be issued. However, the connect does not occur and the SIGALRM is not issued, so the code waits forever (or whatever the actual system timeout value is for connect).

    Can someone explain why the SIGALRM is not issued in this case? Is there some other method that would work better as a timeout enabler in this case? I tried setitimer with the same results.

    Is there some way to detect a system in this 'funny' state so I'll know not to issue the connect at all?

    We're running RH Linux with a 2.6 kernel.
     
    kenakahn, Nov 7, 2012
    #1
    1. Advertisements

  2. NB that printf() and exit() aren’t async-signal safe.
    I suggest using strace to be 100% sure what’s going on inside your
    process.
     
    Richard Kettlewell, Nov 7, 2012
    #2
    1. Advertisements

  3. kenakahn

    kenakahn Guest

    I did some more research and found an old post (2003) that had a solution that seems to work.

    fcntl(socket_hdl,F_SETFL,O_NONBLOCK);

    signal(SIGALRM,Timed_Out);
    alarm(Response_timeout);

    if ((connect(socket_hdl,(struct sockaddr *)&sin,sizeof(sin)) == -1) &&
    (errno != EINPROGRESS)) {
    printf("ERROR: Could not connect to server (rc=%d): %s\n",
    errno,strerror(errno));
    close(socket_hdl);
    return 0;
    }

    fcntl(socket_hdl,F_SETFL,fcntl(socket_hdl,F_GETFL) & ~O_NONBLOCK);
    signal(SIGALRM,SIG_IGN);
     
    kenakahn, Nov 7, 2012
    #3
  4. kenakahn

    kenakahn Guest

    I saw some code that used long jump to get around this problem for SIGALRM.I'll try that.
    I keep forgetting about this. Thanks for the reminder.
     
    kenakahn, Nov 7, 2012
    #4
  5. kenakahn

    Jorgen Grahn Guest

    And tcpdump to be 100% what that 'sick' host does. The OP seems to
    treat it like a mystery, but it's a simple matter[0] to check its
    *externally visible* behavior and how it differs from others
    un-connectable ones.

    /Jorgen

    [0] I assume he has root access on the systems.
     
    Jorgen Grahn, Nov 7, 2012
    #5
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.