示例#1
0
int make_sockets(SOCKET fd[2]) { /* make a pair of connected ipv4 sockets */
#ifdef INET_SOCKET_PAIR
    struct sockaddr_in addr;
    socklen_t addrlen;
    SOCKET s; /* temporary socket awaiting for connection */

    /* create two *blocking* sockets first */
    s=s_socket(AF_INET, SOCK_STREAM, 0, 0, "make_sockets: s_socket#1");
    if(s==INVALID_SOCKET)
        return 1;
    fd[1]=s_socket(AF_INET, SOCK_STREAM, 0, 0, "make_sockets: s_socket#2");
    if(fd[1]==INVALID_SOCKET) {
        closesocket(s);
        return 1;
    }

    addrlen=sizeof addr;
    memset(&addr, 0, sizeof addr);
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    addr.sin_port=htons(0); /* dynamic port allocation */
    if(bind(s, (struct sockaddr *)&addr, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "make_sockets: bind#1");
    if(bind(fd[1], (struct sockaddr *)&addr, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "make_sockets: bind#2");

    if(listen(s, 1)) {
        sockerror("make_sockets: listen");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    if(getsockname(s, (struct sockaddr *)&addr, &addrlen)) {
        sockerror("make_sockets: getsockname");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    if(connect(fd[1], (struct sockaddr *)&addr, addrlen)) {
        sockerror("make_sockets: connect");
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    fd[0]=s_accept(s, (struct sockaddr *)&addr, &addrlen, 1,
        "make_sockets: s_accept");
    if(fd[0]==INVALID_SOCKET) {
        closesocket(s);
        closesocket(fd[1]);
        return 1;
    }
    closesocket(s); /* don't care about the result */
    set_nonblock(fd[0], 1);
    set_nonblock(fd[1], 1);
#else
    if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "make_sockets: socketpair"))
        return 1;
#endif
    return 0;
}
示例#2
0
文件: client.c 项目: l7s/stunnel
static void make_sockets(CLI *c, int fd[2]) { /* make a pair of connected sockets */
#ifdef INET_SOCKET_PAIR
    SOCKADDR_UNION addr;
    socklen_t addrlen;
    int s; /* temporary socket awaiting for connection */

    s=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#1");
    if(s<0)
        longjmp(c->err, 1);
    c->fd=s_socket(AF_INET, SOCK_STREAM, 0, 1, "socket#2");
    if(c->fd<0)
        longjmp(c->err, 1);

    addrlen=sizeof addr;
    memset(&addr, 0, addrlen);
    addr.in.sin_family=AF_INET;
    addr.in.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
    addr.in.sin_port=htons(0); /* dynamic port allocation */
    if(bind(s, &addr.sa, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "bind#1");
    if(bind(c->fd, &addr.sa, addrlen))
        log_error(LOG_DEBUG, get_last_socket_error(), "bind#2");

    if(listen(s, 1)) {
        closesocket(s);
        sockerror("listen");
        longjmp(c->err, 1);
    }
    if(getsockname(s, &addr.sa, &addrlen)) {
        closesocket(s);
        sockerror("getsockname");
        longjmp(c->err, 1);
    }
    if(connect_blocking(c, &addr, addr_len(addr))) {
        closesocket(s);
        longjmp(c->err, 1);
    }
    fd[0]=s_accept(s, &addr.sa, &addrlen, 1, "accept");
    if(fd[0]<0) {
        closesocket(s);
        longjmp(c->err, 1);
    }
    fd[1]=c->fd;
    c->fd=-1;
    closesocket(s); /* don't care about the result */
#else
    if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, fd, 1, "socketpair"))
        longjmp(c->err, 1);
#endif
}
示例#3
0
int libwrap_init() {
#ifdef USE_PTHREAD
    int i, j, rfd, result;
    char servname[SERVNAME_LEN];
    static int initialized=0;
    SERVICE_OPTIONS *opt;

    if(initialized) /* during startup or previous configuration file reload */
        return 0;
    for(opt=service_options.next; opt; opt=opt->next)
        if(opt->option.libwrap) /* libwrap is enabled for this service */
            break;
    if(!opt) /* disabled for all sections or inetd mode (no sections) */
        return 0;

    num_processes=LIBWRAP_CLIENTS;
    ipc_socket=str_alloc(2*num_processes*sizeof(int));
    busy=str_alloc(num_processes*sizeof(int));
    for(i=0; i<num_processes; ++i) { /* spawn a child */
        if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, ipc_socket+2*i, 0, "libwrap_init"))
            return 1;
        switch(fork()) {
        case -1:    /* error */
            ioerror("fork");
            return 1;
        case  0:    /* child */
            drop_privileges(0); /* libwrap processes are not chrooted */
            close(0); /* stdin */
            close(1); /* stdout */
            if(!global_options.option.foreground) /* for logging in read_fd */
                close(2); /* stderr */
            for(j=0; j<=i; ++j) /* close parent-side sockets created so far */
                close(ipc_socket[2*j]);
            while(1) { /* main libwrap child loop */
                if(read_fd(ipc_socket[2*i+1], servname, SERVNAME_LEN, &rfd)<=0)
                    _exit(0);
                result=check(servname, rfd);
                write(ipc_socket[2*i+1], (u8 *)&result, sizeof result);
                if(rfd>=0)
                    close(rfd);
            }
        default:    /* parent */
            close(ipc_socket[2*i+1]); /* child-side socket */
        }
    }
    initialized=1;
#endif /* USE_PTHREAD */
    return 0;
}
示例#4
0
文件: libwrap.c 项目: l7s/stunnel
void libwrap_init(int num) {
#ifdef USE_PTHREAD
    int i, j, rfd, result;
    char servname[SERVNAME_LEN];

    num_processes=num;
    if(!num_processes) /* no extra processes to spawn */
        return;
    ipc_socket=str_alloc(2*num_processes*sizeof(int));
    busy=str_alloc(num_processes*sizeof(int));
    if(!ipc_socket || !busy) {
        s_log(LOG_ERR, "Memory allocation failed");
        die(1);
    }
    for(i=0; i<num_processes; ++i) { /* spawn a child */
        if(s_socketpair(AF_UNIX, SOCK_STREAM, 0, ipc_socket+2*i, 0, "libwrap_init"))
            die(1);
        switch(fork()) {
        case -1:    /* error */
            ioerror("fork");
            die(1);
        case  0:    /* child */
            drop_privileges(); /* libwrap processes are not chrooted */
            close(0); /* stdin */
            close(1); /* stdout */
            if(!global_options.option.foreground) /* for logging in read_fd */
                close(2); /* stderr */
            for(j=0; j<=i; ++j) /* close parent-side sockets created so far */
                close(ipc_socket[2*j]);
            while(1) { /* main libwrap child loop */
                if(read_fd(ipc_socket[2*i+1], servname, SERVNAME_LEN, &rfd)<=0)
                    _exit(0);
                result=check(servname, rfd);
                write(ipc_socket[2*i+1], (u8 *)&result, sizeof result);
                if(rfd>=0)
                    close(rfd);
            }
        default:    /* parent */
            close(ipc_socket[2*i+1]); /* child-side socket */
        }
    }
#endif /* USE_PTHREAD */
}