bypass4netns icon indicating copy to clipboard operation
bypass4netns copied to clipboard

Handle socket(2)'s arguments

Open naoki9911 opened this issue 5 months ago • 1 comments

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 avatar Aug 29 '24 02:08 naoki9911