freebsd: unix socket programmering

From: Michael Rasmussen (none@mir--datanom.net.lh.bsd-dk.dk)
Date: Sun 04 May 2008 - 12:08:17 CEST


Date: Sun, 4 May 2008 12:08:17 +0200
From: Michael Rasmussen <none@mir--datanom.net.lh.bsd-dk.dk>
To: bsd-dk@bsd-dk.dk
Subject: freebsd: unix socket programmering

Hej alle,

Haves: Et besynderligt problem, jeg ikke ved, hvordan jeg skal løse.
Indsats: Alt (synes jeg selv :-)
Ønskes: En forklaring

$ uname -r
7.0-RELEASE
$ clamdscan -V
ClamAV 0.92.1
$ gcc --version
gcc (GCC) 4.2.1 20070719 [FreeBSD]

Programmet fejler konsekvent ved anvendelse af unix socket, men
fungerer upåklageligt med internet socket. Test afviklet på en Debian
boks viser, at her virker både unix socket og internet socket.

source:
static void create_socket() {
    socklen_t addrlen;
    struct sockaddr_un addr_u;
    struct sockaddr_in addr_i;
    struct hostent *hp;

    memset(&addr_u, 0, sizeof(struct sockaddr_un));
    memset(&addr_i, 0, sizeof(struct sockaddr_in));
    debug_print("socket->type: %d\n", Socket->type);
    switch (Socket->type) {
        case UNIX_SOCKET:
            debug_print("socket path: %s\n", Socket->socket.path);
            addr_u.sun_family = AF_UNIX;
            memcpy(addr_u.sun_path, Socket->socket.path,
                            strlen(Socket->socket.path));
            addrlen = sizeof(addr_u.sun_family) +
strlen(addr_u.sun_path); debug_print("sun_path: %s, strlen: %d\n",
addr_u.sun_path, addrlen); sock = socket(PF_UNIX, SOCK_STREAM, 0);
            debug_print("socket file (create): %d\n", sock);
            if (sock < 0)
                return;
            struct stat info;
            if (connect(sock, (struct sockaddr *) &addr_u, addrlen) <
0) { perror("connect");
                if (stat(addr_u.sun_path, &info) < 0)
                    perror("stat");
                sock = -2;
            }
            debug_print("socket file (connect): %d\n", sock);
            break;
        case INET_SOCKET:
            addr_i.sin_family = AF_INET;
            addr_i.sin_port = htons(Socket->socket.port);
            hp = gethostbyname(Socket->socket.host);
            bcopy((void *)hp->h_addr, (void *)&addr_i.sin_addr,
hp->h_length); sock = socket(PF_INET, SOCK_STREAM, 0);
            if (sock < 0)
                return;
            if (connect(sock, (struct sockaddr *)&addr_i,
sizeof(addr_i)) < 0) sock = -2;
            break;
    }
}

Debug fra konsol:
clamav_plugin_gtk.c:360:Clamd GTK plugin loaded
clamav_plugin.c:225:Creating socket
clamav_plugin.c:227:clamd.conf: /usr/local/etc/clamd.conf
clamd-plugin.c:67:Opening /usr/local/etc/clamd.conf to parse config file
clamd-plugin.c:101:clamctl: /var/run/clamav/clamd
clamd-plugin.c:172:socket->type: 0
clamd-plugin.c:175:socket path: /var/run/clamav/clamd
clamd-plugin.c:180:sun_path: /var/run/clamav/clamd, strlen: 22
clamd-plugin.c:182:socket file (create): 15
connect: No such file or directory
clamd-plugin.c:192:socket file (connect): -2
clamd-plugin.c:241:no connection

$ ll /var/run/clamav/clamd
srwxrwxrwx 1 clamav clamav 0 May 4 11:28 /var/run/clamav/clamd

Som det ses fra debug:
1) findes reference til clamd's unix korrekt, som angivet i
/usr/local/etc/clamd.conf
2) socket findes, og rettigheder er 777
3) Der hvor den fejler, udføres en stat, der ikke giver fejl, hvorfor
det må anses, at programmet også finder clamd's unix socket i
filsystemet.

Derfor er min konklusion, at der må ske en fejlkonvertering i følgende
instruktion: (struct sockaddr *) &addr_u

Nogen der har et bud?



This archive was generated by hypermail 2b30 : Sat 31 May 2008 - 23:00:01 CEST