示例#1
0
文件: io.c 项目: caeies/polipo-caeies
FdEventHandlerPtr
do_connect(AtomPtr addr, int index, int port,
           int (*handler)(int, FdEventHandlerPtr, ConnectRequestPtr),
           void *data)
{
    ConnectRequestRec request;
    FdEventHandlerPtr event;
    int done, fd, af;

    assert(addr->length > 0 && addr->string[0] == DNS_A);
    assert(addr->length % sizeof(HostAddressRec) == 1);

    if(index >= (addr->length - 1)/ sizeof(HostAddressRec))
        index = 0;

    request.firstindex = index;
    request.port = port;
    request.handler = handler;
    request.data = data;
 again:
    af = addr->string[1 + index * sizeof(HostAddressRec)];
    fd = serverSocket(af);

    request.fd = fd;
    request.af = af;
    request.addr = addr;
    request.index = index;

    if(fd < 0) {
        int n = (addr->length - 1) / sizeof(HostAddressRec);
        if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
            if((index + 1) % n != request.firstindex) {
                index = (index + 1) % n;
                goto again;
            }
        }
        do_log_error(L_ERROR, errno, "Couldn't create socket");
        done = (*handler)(-errno, NULL, &request);
        assert(done);
        return NULL;
    }

    /* POLLIN is apparently needed on Windows */
    event = registerFdEvent(fd, POLLIN | POLLOUT,
                            do_scheduled_connect,
                            sizeof(ConnectRequestRec), &request);
    if(event == NULL) {
        done = (*handler)(-ENOMEM, NULL, &request);
        assert(done);
        return NULL;
    }

    done = event->handler(0, event);
    if(done) {
        unregisterFdEvent(event);
        return NULL;
    }
    return event;
}
示例#2
0
文件: io.c 项目: caeies/polipo-caeies
int
lingeringClose(int fd)
{
    int rc;
    LingeringClosePtr l;

    rc = shutdown(fd, 1);
    if(rc < 0) {
        if(errno != ENOTCONN) {
            do_log_error(L_ERROR, errno, "Shutdown failed");
        } else if(errno == EFAULT || errno == EBADF) {
            abort();
        }
        CLOSE(fd);
        return 1;
    }

    l = malloc(sizeof(LingeringCloseRec));
    if(l == NULL)
        goto fail;
    l->fd = fd;
    l->handler = NULL;
    l->timeout = NULL;

    l->timeout = scheduleTimeEvent(10, lingeringCloseTimeoutHandler,
                                   sizeof(LingeringClosePtr), &l);
    if(l->timeout == NULL) {
        free(l);
        goto fail;
    }

    l->handler = registerFdEvent(fd, POLLIN,
                                 lingeringCloseHandler,
                                 sizeof(LingeringClosePtr), &l);
    if(l->handler == NULL) {
        do_log(L_ERROR, "Couldn't schedule lingering close handler.\n");
        /* But don't close -- the timeout will do its work. */
    }
    return 1;

 fail:
    do_log(L_ERROR, "Couldn't schedule lingering close.\n");
    CLOSE(fd);
    return 1;
}
示例#3
0
文件: dns.c 项目: fukusaka/polipo
static int
establishDnsSocket()
{
    int rc;
#ifdef HAVE_IPv6
    int inet6 = (nameserverAddress.sa_family == AF_INET6);
    int pf = inet6 ? PF_INET6 : PF_INET;
    int sa_size = 
        inet6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
#else
    int pf = PF_INET;
    int sa_size = sizeof(struct sockaddr_in);
#endif

    if(dnsSocket < 0) {
        assert(!dnsSocketHandler);
        dnsSocket = socket(pf, SOCK_DGRAM, 0);
        if(dnsSocket < 0) {
            do_log_error(L_ERROR, errno, "Couldn't create DNS socket");
            return -errno;
        }

        rc = connect(dnsSocket, &nameserverAddress, sa_size);
        if(rc < 0) {
            CLOSE(dnsSocket);
            dnsSocket = -1;
            do_log_error(L_ERROR, errno, "Couldn't create DNS \"connection\"");
            return -errno;
        }
    }

    if(!dnsSocketHandler) {
        dnsSocketHandler = 
            registerFdEvent(dnsSocket, POLLIN, dnsReplyHandler, 0, NULL);
        if(dnsSocketHandler == NULL) {
            do_log(L_ERROR, "Couldn't register DNS socket handler.\n");
            CLOSE(dnsSocket);
            dnsSocket = -1;
            return -ENOMEM;
        }
    }

    return 1;
}
示例#4
0
文件: io.c 项目: caeies/polipo-caeies
FdEventHandlerPtr
schedule_accept(int fd,
                int (*handler)(int, FdEventHandlerPtr, AcceptRequestPtr),
                void *data)
{
    FdEventHandlerPtr event;
    AcceptRequestRec request;
    int done;

    request.fd = fd;
    request.handler = handler;
    request.data = data;
    event = registerFdEvent(fd, POLLOUT|POLLIN, 
                            do_scheduled_accept, sizeof(request), &request);
    if(!event) {
        done = (*handler)(-ENOMEM, NULL, NULL);
        assert(done);
    }
    return event;
}