View | Details | Raw Unified | Return to bug 331791 | Differences between
and this patch

Collapse All | Expand All

(-)framework/channel_tcp.c (-36 / +123 lines)
Lines 24-29 Link Here
24
#include <errno.h>
24
#include <errno.h>
25
#include <assert.h>
25
#include <assert.h>
26
#include <sys/stat.h>
26
#include <sys/stat.h>
27
#include <ctype.h>
27
#if ENABLE_SSL
28
#if ENABLE_SSL
28
#  include <openssl/ssl.h>
29
#  include <openssl/ssl.h>
29
#  include <openssl/rand.h>
30
#  include <openssl/rand.h>
Lines 643-669 Link Here
643
    ibuf_trigger_read(&c->ibuf);
644
    ibuf_trigger_read(&c->ibuf);
644
}
645
}
645
646
646
static ChannelTCP * create_channel(int sock, int en_ssl, int server) {
647
static ChannelTCP * create_channel(int sock, int en_ssl, int server, int unix_domain) {
647
    const int i = 1;
648
    const int i = 1;
648
    ChannelTCP * c = NULL;
649
    ChannelTCP * c = NULL;
649
    SSL * ssl = NULL;
650
    SSL * ssl = NULL;
650
651
651
    assert(sock >= 0);
652
    assert(sock >= 0);
652
    if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) {
653
    if (!unix_domain) {
653
        int error = errno;
654
		if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&i, sizeof(i)) < 0) {
654
        trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(error));
655
			int error = errno;
655
        closesocket(sock);
656
			trace(LOG_ALWAYS, "Can't set TCP_NODELAY option on a socket: %s", errno_to_str(error));
656
        errno = error;
657
			closesocket(sock);
657
        return NULL;
658
			errno = error;
659
			return NULL;
660
		}
661
		if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)) < 0) {
662
			int error = errno;
663
			trace(LOG_ALWAYS, "Can't set SO_KEEPALIVE option on a socket: %s", errno_to_str(error));
664
			closesocket(sock);
665
			errno = error;
666
			return NULL;
667
		}
658
    }
668
    }
659
    if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, sizeof(i)) < 0) {
669
    
660
        int error = errno;
661
        trace(LOG_ALWAYS, "Can't set SO_KEEPALIVE option on a socket: %s", errno_to_str(error));
662
        closesocket(sock);
663
        errno = error;
664
        return NULL;
665
    }
666
667
    if (en_ssl) {
670
    if (en_ssl) {
668
#if ENABLE_SSL
671
#if ENABLE_SSL
669
        long opts = 0;
672
        long opts = 0;
Lines 850-856 Link Here
850
    sock = req->u.acc.rval;
853
    sock = req->u.acc.rval;
851
    peer_addr = si->addr;
854
    peer_addr = si->addr;
852
    async_req_post(req);
855
    async_req_post(req);
853
    c = create_channel(sock, strcmp(peer_server_getprop(si->ps, "TransportName", ""), "SSL") == 0, 1);
856
    c = create_channel(sock, strcmp(peer_server_getprop(si->ps, "TransportName", ""), "SSL") == 0, 1,
857
    		peer_addr.sa_family == AF_UNIX);
854
    if (c == NULL) return;
858
    if (c == NULL) return;
855
    set_peer_addr(c, &peer_addr);
859
    set_peer_addr(c, &peer_addr);
856
    si->serv.new_conn(&si->serv, &c->chan);
860
    si->serv.new_conn(&si->serv, &c->chan);
Lines 875-880 Link Here
875
    setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcv_buf, sizeof(rcv_buf));
879
    setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcv_buf, sizeof(rcv_buf));
876
}
880
}
877
881
882
static ChannelServer * channel_server_create(PeerServer * ps, int sock) {
883
    ServerTCP * si;
884
885
    si = (ServerTCP *)loc_alloc_zero(sizeof *si);
886
    si->serv.close = server_close;
887
    si->sock = sock;
888
    si->ps = ps;
889
    if (server_list.next == NULL) list_init(&server_list);
890
    if (list_is_empty(&server_list)) {
891
        post_event_with_delay(refresh_all_peer_server, NULL, PEER_DATA_REFRESH_PERIOD * 1000000);
892
    }
893
    list_add_last(&si->servlink, &server_list);
894
    refresh_peer_server(sock, ps);
895
896
    si->accreq.done = tcp_server_accept_done;
897
    si->accreq.client_data = si;
898
    si->accreq.type = AsyncReqAccept;
899
    si->accreq.u.acc.sock = sock;
900
    si->accreq.u.acc.addr = &si->addr;
901
    si->accreq.u.acc.addrlen = sizeof(si->addr);
902
    async_req_post(&si->accreq);
903
    return &si->serv;
904
}
905
906
ChannelServer * channel_unix_server(PeerServer * ps) {
907
    int sock;
908
    int error;
909
    const char* reason = 0;
910
    struct sockaddr_un localhost;
911
    
912
    const char * host = peer_server_getprop(ps, "Host", NULL);
913
    if (host == NULL) {
914
    	errno = ERR_UNKNOWN_PEER; 
915
    	return NULL;
916
    }
917
    
918
    assert(is_dispatch_thread());
919
    
920
    memset(&localhost, 0, sizeof localhost);
921
    
922
    trace(LOG_ALWAYS, "Configuring Unix domain socket on %s for local connection", host);
923
    
924
    error = 0;
925
    
926
    if (strlen(host) >= sizeof(localhost.sun_path))
927
	{
928
    	errno = E2BIG;
929
		trace(LOG_ALWAYS, "Socket file path is too long (%d > %d)", strlen(host), sizeof(localhost.sun_path) - 1);
930
		return NULL;
931
    }
932
    
933
    sock = socket(PF_UNIX, SOCK_STREAM, 0);
934
    if (sock < 0) {
935
        error = errno;
936
        trace(LOG_ALWAYS, "Socket create error on %s: %s", reason, host, errno_to_str(error));
937
        return NULL;
938
    }
939
    
940
	set_socket_buffer_sizes(sock);
941
	
942
	memset((void*)&localhost, 0, sizeof(localhost));
943
	
944
	localhost.sun_family = AF_UNIX;
945
	// length checked above
946
	strncpy(localhost.sun_path, host, sizeof(localhost.sun_path));
947
948
#if defined _WIN32 || defined __SYMBIAN32__
949
	// For Windows and Symbian, the path needs to be in Unix format 
950
	// (the ':' will otherwise delineate the unused port), so convert that back
951
	// to an actual host filename
952
	if (host[0] == '/' && isalpha(host[1]) && host[2] == '/') {
953
		localhost.sun_path[0] = localhost.sun_path[1];
954
		localhost.sun_path[1] = ':';
955
	}
956
#endif        
957
    
958
	if (bind(sock, (struct sockaddr *)&localhost, SUN_LEN(&localhost))) {
959
		error = errno;
960
		reason = "bind";
961
		close(sock);
962
		sock = -1;
963
	}
964
	
965
	if (!error && listen(sock, 16)) {
966
		error = errno;
967
		reason = "listen";
968
		close(sock);
969
		sock = -1;
970
	}
971
972
    if (sock < 0) {
973
        trace(LOG_ALWAYS, "Socket %s error on %s: %s", reason, localhost.sun_path, errno_to_str(error));
974
        errno = error;
975
        return NULL;
976
    }
977
    
978
    return channel_server_create(ps, sock);
979
}
980
981
878
ChannelServer * channel_tcp_server(PeerServer * ps) {
982
ChannelServer * channel_tcp_server(PeerServer * ps) {
879
    int sock;
983
    int sock;
880
    int error;
984
    int error;
Lines 967-991 Link Here
967
        errno = error;
1071
        errno = error;
968
        return NULL;
1072
        return NULL;
969
    }
1073
    }
970
    si = (ServerTCP *)loc_alloc_zero(sizeof *si);
1074
    
971
    si->serv.close = server_close;
1075
    return channel_server_create(ps, sock);
972
    si->sock = sock;
973
    si->ps = ps;
974
    if (server_list.next == NULL) list_init(&server_list);
975
    if (list_is_empty(&server_list)) {
976
        post_event_with_delay(refresh_all_peer_server, NULL, PEER_DATA_REFRESH_PERIOD * 1000000);
977
    }
978
    list_add_last(&si->servlink, &server_list);
979
    refresh_peer_server(sock, ps);
980
981
    si->accreq.done = tcp_server_accept_done;
982
    si->accreq.client_data = si;
983
    si->accreq.type = AsyncReqAccept;
984
    si->accreq.u.acc.sock = sock;
985
    si->accreq.u.acc.addr = &si->addr;
986
    si->accreq.u.acc.addrlen = sizeof(si->addr);
987
    async_req_post(&si->accreq);
988
    return &si->serv;
989
}
1076
}
990
1077
991
typedef struct ChannelConnectInfo {
1078
typedef struct ChannelConnectInfo {
Lines 1005-1011 Link Here
1005
        closesocket(info->sock);
1092
        closesocket(info->sock);
1006
    }
1093
    }
1007
    else {
1094
    else {
1008
        ChannelTCP * c = create_channel(info->sock, info->ssl, 0);
1095
        ChannelTCP * c = create_channel(info->sock, info->ssl, 0, info->peer_addr.sa_family == AF_UNIX);
1009
        if (c == NULL) {
1096
        if (c == NULL) {
1010
            info->callback(info->callback_args, errno, NULL);
1097
            info->callback(info->callback_args, errno, NULL);
1011
            closesocket(info->sock);
1098
            closesocket(info->sock);
(-)framework/channel_tcp.h (-1 / +6 lines)
Lines 22-31 Link Here
22
#include <framework/channel.h>
22
#include <framework/channel.h>
23
23
24
/*
24
/*
25
 * Start TCP channel listener.
25
 * Start TCP (Internet) channel listener.
26
 * On error returns NULL and sets errno.
26
 * On error returns NULL and sets errno.
27
 */
27
 */
28
extern ChannelServer * channel_tcp_server(PeerServer * server);
28
extern ChannelServer * channel_tcp_server(PeerServer * server);
29
/*
30
 * Start TCP (Unix domain socket) channel listener.
31
 * On error returns NULL and sets errno.
32
 */
33
extern ChannelServer * channel_unix_server(PeerServer * server);
29
34
30
/*
35
/*
31
 * Connect client side over TCP.
36
 * Connect client side over TCP.
(-)framework/channel.c (-1 / +4 lines)
Lines 235-240 Link Here
235
    else if (strcmp(transportname, "PIPE") == 0) {
235
    else if (strcmp(transportname, "PIPE") == 0) {
236
        return channel_pipe_server(ps);
236
        return channel_pipe_server(ps);
237
    }
237
    }
238
    else if (strcmp(transportname, "UNIX") == 0) {
239
        return channel_unix_server(ps);
240
    }
238
    else {
241
    else {
239
        errno = ERR_INV_TRANSPORT;
242
        errno = ERR_INV_TRANSPORT;
240
        return NULL;
243
        return NULL;
Lines 264-270 Link Here
264
void channel_start(Channel * c) {
267
void channel_start(Channel * c) {
265
    trace(LOG_PROTOCOL, "Starting channel %#lx %s", c, c->peer_name);
268
    trace(LOG_PROTOCOL, "Starting channel %#lx %s", c, c->peer_name);
266
    assert(c->protocol != NULL);
269
    assert(c->protocol != NULL);
267
    assert(c->state == ChannelStateStartWait);
270
    assert(c->always_connected || c->state == ChannelStateStartWait);
268
    c->state = ChannelStateStarted;
271
    c->state = ChannelStateStarted;
269
    c->start_comm(c);
272
    c->start_comm(c);
270
}
273
}

Return to bug 331791