Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle socket(2)'s arguments #89

Open
naoki9911 opened this issue Aug 29, 2024 · 1 comment
Open

Handle socket(2)'s arguments #89

naoki9911 opened this issue Aug 29, 2024 · 1 comment

Comments

@naoki9911
Copy link
Collaborator

Some applications call socket(2) with SOCK_CLOEXEC or SOCK_NONBLOCK.
getsockopt(fd, SOL_SOCKET, SO_TYPE, ...) returns only its actual type SOCK_STREAM and these flags are ignored.
These flags must be checked and included in host-side socket creation.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>

int main() {
    int sock_flags[3] = {SOCK_STREAM, SOCK_STREAM|SOCK_CLOEXEC, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK};
    char* sock_flags_str[3] = {"SOCK_STREAM", "SOCK_STREMA|SOCK_CLOEXEC", "SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK"};
    for (int i = 0; i < 3; i++) {
        int sock_flag = sock_flags[i];
        printf("socket %s flags=0x%x\n", sock_flags_str[i], sock_flags[i]);
        int sock = socket(AF_INET, sock_flag, 0);
        if (sock == -1) 
        {
            perror("socket");
            return -1;
        }

        int opt;
        int opt_len = sizeof(opt);
        int err = getsockopt(sock, SOL_SOCKET, SO_TYPE, &opt, &opt_len);
        if (err == -1)
        {
            perror("getsockopt");
            return -1;
        }
        printf("SOL_SOCKET SO_TYPE=0x%x\n", opt);

        int flags = fcntl(sock, F_GETFD);
        printf("F_GETFD flags=0x%x\n", flags);
        printf("CLOEXEC=%d\n", (flags & FD_CLOEXEC) > 0);
        flags = fcntl(sock, F_GETFL);
        printf("F_GETFL flags=0x%x\n", flags);
        printf("NON_BLOCK=%d\n", (flags & O_NONBLOCK) > 0);
        printf("\n");

        close(sock);
    }
}
$ ./check_sock
socket SOCK_STREAM flags=0x1
SOL_SOCKET SO_TYPE=0x1
F_GETFD flags=0x0
CLOEXEC=0
F_GETFL flags=0x2
NON_BLOCK=0

socket SOCK_STREMA|SOCK_CLOEXEC flags=0x80001
SOL_SOCKET SO_TYPE=0x1
F_GETFD flags=0x1
CLOEXEC=1
F_GETFL flags=0x2
NON_BLOCK=0

socket SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK flags=0x80801
SOL_SOCKET SO_TYPE=0x1
F_GETFD flags=0x1
CLOEXEC=1
F_GETFL flags=0x802
NON_BLOCK=1
@naoki9911
Copy link
Collaborator Author

Cited from man socket(2)

     Since Linux 2.6.27, the type argument serves a second purpose: in addition  to
       specifying  a socket type, it may include the bitwise OR of any of the follow‐
       ing values, to modify the behavior of socket():

       SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on the open file  descrip‐
                       tion  (see  open(2))  referred  to by the new file descriptor.
                       Using this flag saves extra calls to fcntl(2) to  achieve  the
                       same result.

       SOCK_CLOEXEC    Set  the  close-on-exec  (FD_CLOEXEC) flag on the new file de‐
                       scriptor.  See  the  description  of  the  O_CLOEXEC  flag  in
                       open(2) for reasons why this may be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant