Commit e6215938 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

rpcrt4: Always use winsock for networking.

parent efdb722c
......@@ -2,8 +2,7 @@ EXTRADEFS = -D_RPCRT4_ -DMSWMSG
MODULE = rpcrt4.dll
IMPORTLIB = rpcrt4
IMPORTS = uuid advapi32
DELAYIMPORTS = iphlpapi wininet secur32 user32
EXTRALIBS = $(SOCKET_LIBS)
DELAYIMPORTS = iphlpapi wininet secur32 user32 ws2_32
C_SRCS = \
cproxy.c \
......
......@@ -23,62 +23,14 @@
*
*/
#include "config.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "ws2tcpip.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#if defined(__MINGW32__) || defined (_MSC_VER)
# include <ws2tcpip.h>
# ifndef EADDRINUSE
# define EADDRINUSE WSAEADDRINUSE
# endif
# ifndef EAGAIN
# define EAGAIN WSAEWOULDBLOCK
# endif
# undef errno
# define errno WSAGetLastError()
#else
# include <errno.h>
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# include <fcntl.h>
# ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
# endif
# ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
# endif
# ifdef HAVE_NETINET_TCP_H
# include <netinet/tcp.h>
# endif
# ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
# endif
# ifdef HAVE_NETDB_H
# include <netdb.h>
# endif
# ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
# endif
# ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
# endif
# ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
# endif
# define closesocket close
# define ioctlsocket ioctl
#endif /* defined(__MINGW32__) || defined (_MSC_VER) */
#include "windef.h"
#include "winbase.h"
......@@ -99,10 +51,6 @@
#include "rpc_server.h"
#include "epm_towers.h"
#ifndef SOL_TCP
# define SOL_TCP IPPROTO_TCP
#endif
#define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000)
#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0]))
......@@ -1057,7 +1005,7 @@ static RPC_STATUS rpcrt4_ip_tcp_parse_top_of_tower(const unsigned char *tower_da
in_addr.s_addr = ipv4_floor->ipv4addr;
if (!inet_ntop(AF_INET, &in_addr, *networkaddr, INET_ADDRSTRLEN))
{
ERR("inet_ntop: %s\n", strerror(errno));
ERR("inet_ntop: %u\n", WSAGetLastError());
I_RpcFree(*networkaddr);
*networkaddr = NULL;
if (endpoint)
......@@ -1076,75 +1024,10 @@ typedef struct _RpcConnection_tcp
{
RpcConnection common;
int sock;
#ifdef HAVE_SOCKETPAIR
int cancel_fds[2];
#else
HANDLE sock_event;
HANDLE cancel_event;
#endif
} RpcConnection_tcp;
#ifdef HAVE_SOCKETPAIR
static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
{
if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
{
ERR("socketpair() failed: %s\n", strerror(errno));
return FALSE;
}
return TRUE;
}
static BOOL rpcrt4_sock_wait_for_recv(RpcConnection_tcp *tcpc)
{
struct pollfd pfds[2];
pfds[0].fd = tcpc->sock;
pfds[0].events = POLLIN;
pfds[1].fd = tcpc->cancel_fds[0];
pfds[1].events = POLLIN;
if (poll(pfds, 2, -1 /* infinite */) == -1 && errno != EINTR)
{
ERR("poll() failed: %s\n", strerror(errno));
return FALSE;
}
if (pfds[1].revents & POLLIN) /* canceled */
{
char dummy;
read(pfds[1].fd, &dummy, sizeof(dummy));
return FALSE;
}
return TRUE;
}
static BOOL rpcrt4_sock_wait_for_send(RpcConnection_tcp *tcpc)
{
struct pollfd pfd;
pfd.fd = tcpc->sock;
pfd.events = POLLOUT;
if (poll(&pfd, 1, -1 /* infinite */) == -1 && errno != EINTR)
{
ERR("poll() failed: %s\n", strerror(errno));
return FALSE;
}
return TRUE;
}
static void rpcrt4_sock_wait_cancel(RpcConnection_tcp *tcpc)
{
char dummy = 1;
write(tcpc->cancel_fds[1], &dummy, 1);
}
static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
{
close(tcpc->cancel_fds[0]);
close(tcpc->cancel_fds[1]);
}
#else /* HAVE_SOCKETPAIR */
static BOOL rpcrt4_sock_wait_init(RpcConnection_tcp *tcpc)
{
static BOOL wsa_inited;
......@@ -1221,8 +1104,6 @@ static void rpcrt4_sock_wait_destroy(RpcConnection_tcp *tcpc)
CloseHandle(tcpc->cancel_event);
}
#endif
static RpcConnection *rpcrt4_conn_tcp_alloc(void)
{
RpcConnection_tcp *tcpc;
......@@ -1293,20 +1174,20 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);
if (sock == -1)
{
WARN("socket() failed: %s\n", strerror(errno));
WARN("socket() failed: %u\n", WSAGetLastError());
continue;
}
if (0>connect(sock, ai_cur->ai_addr, ai_cur->ai_addrlen))
{
WARN("connect() failed: %s\n", strerror(errno));
WARN("connect() failed: %u\n", WSAGetLastError());
closesocket(sock);
continue;
}
/* RPC depends on having minimal latency so disable the Nagle algorithm */
val = 1;
setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
nonblocking = 1;
ioctlsocket(sock, FIONBIO, &nonblocking);
......@@ -1380,7 +1261,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
sock = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);
if (sock == -1)
{
WARN("socket() failed: %s\n", strerror(errno));
WARN("socket() failed: %u\n", WSAGetLastError());
status = RPC_S_CANT_CREATE_ENDPOINT;
continue;
}
......@@ -1388,9 +1269,9 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen);
if (ret < 0)
{
WARN("bind failed: %s\n", strerror(errno));
WARN("bind failed: %u\n", WSAGetLastError());
closesocket(sock);
if (errno == EADDRINUSE)
if (WSAGetLastError() == WSAEADDRINUSE)
status = RPC_S_DUPLICATE_ENDPOINT;
else
status = RPC_S_CANT_CREATE_ENDPOINT;
......@@ -1400,7 +1281,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
sa_len = sizeof(sa);
if (getsockname(sock, (struct sockaddr *)&sa, &sa_len))
{
WARN("getsockname() failed: %s\n", strerror(errno));
WARN("getsockname() failed: %u\n", WSAGetLastError());
closesocket(sock);
status = RPC_S_CANT_CREATE_ENDPOINT;
continue;
......@@ -1431,7 +1312,7 @@ static RPC_STATUS rpcrt4_protseq_ncacn_ip_tcp_open_endpoint(RpcServerProtseq *pr
ret = listen(sock, protseq->MaxCalls);
if (ret < 0)
{
WARN("listen failed: %s\n", strerror(errno));
WARN("listen failed: %u\n", WSAGetLastError());
RPCRT4_ReleaseConnection(&tcpc->common);
status = RPC_S_OUT_OF_RESOURCES;
continue;
......@@ -1528,11 +1409,11 @@ static int rpcrt4_conn_tcp_read(RpcConnection *Connection,
return -1;
else if (r > 0)
bytes_read += r;
else if (errno == EINTR)
else if (WSAGetLastError() == WSAEINTR)
continue;
else if (errno != EAGAIN)
else if (WSAGetLastError() != WSAEWOULDBLOCK)
{
WARN("recv() failed: %s\n", strerror(errno));
WARN("recv() failed: %u\n", WSAGetLastError());
return -1;
}
else
......@@ -1555,9 +1436,9 @@ static int rpcrt4_conn_tcp_write(RpcConnection *Connection,
int r = send(tcpc->sock, (const char *)buffer + bytes_written, count - bytes_written, 0);
if (r >= 0)
bytes_written += r;
else if (errno == EINTR)
else if (WSAGetLastError() == WSAEINTR)
continue;
else if (errno != EAGAIN)
else if (WSAGetLastError() != WSAEWOULDBLOCK)
return -1;
else
{
......@@ -1614,149 +1495,6 @@ static size_t rpcrt4_ncacn_ip_tcp_get_top_of_tower(unsigned char *tower_data,
EPM_PROTOCOL_TCP, endpoint);
}
#ifdef HAVE_SOCKETPAIR
typedef struct _RpcServerProtseq_sock
{
RpcServerProtseq common;
int mgr_event_rcv;
int mgr_event_snd;
} RpcServerProtseq_sock;
static RpcServerProtseq *rpcrt4_protseq_sock_alloc(void)
{
RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
if (ps)
{
int fds[2];
if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
{
fcntl(fds[0], F_SETFL, O_NONBLOCK);
fcntl(fds[1], F_SETFL, O_NONBLOCK);
ps->mgr_event_rcv = fds[0];
ps->mgr_event_snd = fds[1];
}
else
{
ERR("socketpair failed with error %s\n", strerror(errno));
HeapFree(GetProcessHeap(), 0, ps);
return NULL;
}
}
return &ps->common;
}
static void rpcrt4_protseq_sock_signal_state_changed(RpcServerProtseq *protseq)
{
RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common);
char dummy = 1;
write(sockps->mgr_event_snd, &dummy, sizeof(dummy));
}
static void *rpcrt4_protseq_sock_get_wait_array(RpcServerProtseq *protseq, void *prev_array, unsigned int *count)
{
struct pollfd *poll_info = prev_array;
RpcConnection_tcp *conn;
RpcServerProtseq_sock *sockps = CONTAINING_RECORD(protseq, RpcServerProtseq_sock, common);
EnterCriticalSection(&protseq->cs);
/* open and count connections */
*count = 1;
conn = (RpcConnection_tcp *)protseq->conn;
while (conn) {
if (conn->sock != -1)
(*count)++;
conn = (RpcConnection_tcp *)conn->common.Next;
}
/* make array of connections */
if (poll_info)
poll_info = HeapReAlloc(GetProcessHeap(), 0, poll_info, *count*sizeof(*poll_info));
else
poll_info = HeapAlloc(GetProcessHeap(), 0, *count*sizeof(*poll_info));
if (!poll_info)
{
ERR("couldn't allocate poll_info\n");
LeaveCriticalSection(&protseq->cs);
return NULL;
}
poll_info[0].fd = sockps->mgr_event_rcv;
poll_info[0].events = POLLIN;
*count = 1;
conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
while (conn) {
if (conn->sock != -1)
{
poll_info[*count].fd = conn->sock;
poll_info[*count].events = POLLIN;
(*count)++;
}
conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
}
LeaveCriticalSection(&protseq->cs);
return poll_info;
}
static void rpcrt4_protseq_sock_free_wait_array(RpcServerProtseq *protseq, void *array)
{
HeapFree(GetProcessHeap(), 0, array);
}
static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq, unsigned int count, void *wait_array)
{
struct pollfd *poll_info = wait_array;
int ret;
unsigned int i;
RpcConnection *cconn;
RpcConnection_tcp *conn;
if (!poll_info)
return -1;
ret = poll(poll_info, count, -1);
if (ret < 0)
{
ERR("poll failed with error %d\n", ret);
return -1;
}
for (i = 0; i < count; i++)
if (poll_info[i].revents & POLLIN)
{
/* RPC server event */
if (i == 0)
{
char dummy;
read(poll_info[0].fd, &dummy, sizeof(dummy));
return 0;
}
/* find which connection got a RPC */
EnterCriticalSection(&protseq->cs);
conn = CONTAINING_RECORD(protseq->conn, RpcConnection_tcp, common);
while (conn) {
if (poll_info[i].fd == conn->sock) break;
conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_tcp, common);
}
cconn = NULL;
if (conn)
RPCRT4_SpawnConnection(&cconn, &conn->common);
else
ERR("failed to locate connection for fd %d\n", poll_info[i].fd);
LeaveCriticalSection(&protseq->cs);
if (cconn)
RPCRT4_new_client(cconn);
else
return -1;
}
return 1;
}
#else /* HAVE_SOCKETPAIR */
typedef struct _RpcServerProtseq_sock
{
RpcServerProtseq common;
......@@ -1898,8 +1636,6 @@ static int rpcrt4_protseq_sock_wait_for_new_connection(RpcServerProtseq *protseq
}
}
#endif /* HAVE_SOCKETPAIR */
static RPC_STATUS rpcrt4_ncacn_ip_tcp_parse_top_of_tower(const unsigned char *tower_data,
size_t tower_size,
char **networkaddr,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment