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); |