コード例 #1
0
ファイル: utils.c プロジェクト: aventado/redsocks
struct bufferevent* red_connect_relay(struct sockaddr_in *addr, evbuffercb writecb, everrorcb errorcb, void *cbarg)
{
	struct bufferevent *retval = NULL;
	int relay_fd = -1;
	int error;

	relay_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (relay_fd == -1) {
		log_errno(LOG_ERR, "socket");
		goto fail;
	}

	error = fcntl_nonblock(relay_fd);
	if (error) {
		log_errno(LOG_ERR, "fcntl");
		goto fail;
	}

	if (apply_tcp_keepalive(relay_fd))
		goto fail;

	error = connect(relay_fd, (struct sockaddr*)addr, sizeof(*addr));
	if (error && errno != EINPROGRESS) {
		log_errno(LOG_NOTICE, "connect");
		goto fail;
	}

	retval = bufferevent_new(relay_fd, NULL, writecb, errorcb, cbarg);
	if (!retval) {
		log_errno(LOG_ERR, "bufferevent_new");
		goto fail;
	}

	error = bufferevent_enable(retval, EV_WRITE); // we wait for connection...
	if (error) {
		log_errno(LOG_ERR, "bufferevent_enable");
		goto fail;
	}

	return retval;

fail:
	if (relay_fd != -1)
		redsocks_close(relay_fd);
	if (retval)
		bufferevent_free(retval);
	return NULL;
}
コード例 #2
0
ファイル: utils.c プロジェクト: rampageX/redsocks
struct bufferevent* red_prepare_relay(const char *ifname,
                                bufferevent_data_cb readcb,
                                bufferevent_data_cb writecb,
                                bufferevent_event_cb errorcb,
                                void *cbarg)
{
    struct bufferevent *retval = NULL;
    int relay_fd = -1;
    int error;

    relay_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (relay_fd == -1) {
        log_errno(LOG_ERR, "socket");
        goto fail;
    }
    if (ifname && strlen(ifname)) {
#ifdef USE_PF // BSD
        error = setsockopt(relay_fd, SOL_SOCKET, IP_RECVIF, ifname, strlen(ifname));
#else // Linux
        error = setsockopt(relay_fd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
#endif
        if (error) {
            log_errno(LOG_ERR, "setsockopt");
            goto fail;
        }
    }
    error = evutil_make_socket_nonblocking(relay_fd);
    if (error) {
        log_errno(LOG_ERR, "evutil_make_socket_nonblocking");
        goto fail;
    }

    retval = bufferevent_socket_new(get_event_base(), relay_fd, 0);
    if (!retval) {
        log_errno(LOG_ERR, "bufferevent_socket_new");
        goto fail;
    }

    bufferevent_setcb(retval, readcb, writecb, errorcb, cbarg);
    if (writecb) {
        error = bufferevent_enable(retval, EV_WRITE); // we wait for connection...
        if (error) {
            log_errno(LOG_ERR, "bufferevent_enable");
            goto fail;
        }
    }

    if (apply_tcp_keepalive(relay_fd))
        goto fail;

    return retval;

fail:
    if (retval){
        bufferevent_disable(retval, EV_READ|EV_WRITE);
        bufferevent_free(retval);
    }
    if (relay_fd != -1)
        redsocks_close(relay_fd);
    return NULL;
}