Dear devs,

I'm trying to get an accept() call to time out using setsockopt.

On Linux, the example below terminates:

[dstaesse@phoneutria]$ gcc accept_st.c -o accept_st
[dstaesse@phoneutria]$ ./accept_st
Timeout is 0:100000.
Check is 0:103333.
Accept returned: Resource temporarily unavailable.
Accept returned: Resource temporarily unavailable.
Accept returned: Resource temporarily unavailable.
Bye.

On FreeBSD 11.0-RELEASE however, it hangs on the accept() forever.

Is this a known issue?

Thanks for your help,

Dimitri

--- example source:

#define _POSIX_C_SOURCE 200809L

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>

#define TIMEOUT 100 /* ms */
#define RUNNING 0
#define SHUTDOWN 1

#define FN "/tmp/accept_st_socket"

int sfd;

void main(void)
{
        int count = 0;
        int cfd;
        struct timeval tv = {(TIMEOUT / 1000), (TIMEOUT % 1000) * 1000};
        struct timeval check;
        socklen_t len = sizeof(check);
        struct sockaddr_un serv_addr;

        printf("Timeout is %lu:%lu.\n", tv.tv_sec, tv.tv_usec);

        sfd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sfd < 0) {
                printf("Failed to open socket: %s.\n", strerror(errno));
                exit(EXIT_FAILURE);
        }

        if (access(FN, F_OK) != -1) {
                /* File exists */
                if (unlink(FN))
                        exit(EXIT_FAILURE);
        }

        serv_addr.sun_family = AF_UNIX;
        sprintf(serv_addr.sun_path, "%s", FN);

        if (bind(sfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) {
                printf("Failed to bind socket: %s.\n", strerror(errno));
                close(sfd);
                exit(EXIT_FAILURE);
        }

        if (listen(sfd, 0)) {
printf("Failed to listen on socket: %s.\n", strerror(errno));
                close(sfd);
                exit(EXIT_FAILURE);
        }

        if (setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, (void *) &tv, len))
                printf("Failed to set timeout on socket: %s.\n",
                       strerror(errno));

        getsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, &check, &len);

        printf("Check is %lu:%lu.\n", check.tv_sec, check.tv_usec);

        while (count < 3) {
                cfd = accept(sfd, 0, 0);
                printf("Accept returned: %s.\n", strerror(errno));
                ++count;
        }

        printf("Bye.\n");

        exit(EXIT_SUCCESS);
}


--
Dimitri Staessens
Ghent University - imec
Dept. of Information Technology (INTEC)
Internet Based Communication Networks and Services
Technologiepark 15
9052 Zwijnaarde
T: +32 9 331 48 70
F: +32 9 331 48 99

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to