Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
48ca6218
Commit
48ca6218
authored
Oct 18, 2006
by
Damjan Jovanovic
Committed by
Alexandre Julliard
Oct 20, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rpcrt4: Added support for RPC TCP servers.
parent
0a20f18a
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
146 additions
and
18 deletions
+146
-18
rpc_transport.c
dlls/rpcrt4/rpc_transport.c
+146
-18
No files found.
dlls/rpcrt4/rpc_transport.c
View file @
48ca6218
...
...
@@ -5,6 +5,7 @@
* Copyright 2003 Mike Hearn
* Copyright 2004 Filip Navara
* Copyright 2006 Mike McCormack
* Copyright 2006 Damjan Jovanovic
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -48,6 +49,9 @@
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#include "windef.h"
#include "winbase.h"
...
...
@@ -448,14 +452,52 @@ typedef struct _RpcConnection_tcp
{
RpcConnection
common
;
int
sock
;
HANDLE
onEventAvailable
;
HANDLE
onEventHandled
;
BOOL
quit
;
}
RpcConnection_tcp
;
static
DWORD
WINAPI
rpcrt4_tcp_poll_thread
(
LPVOID
arg
)
{
RpcConnection_tcp
*
tcpc
;
int
ret
;
struct
pollfd
pollInfo
;
tcpc
=
(
RpcConnection_tcp
*
)
arg
;
pollInfo
.
fd
=
tcpc
->
sock
;
pollInfo
.
events
=
POLLIN
;
while
(
!
tcpc
->
quit
)
{
ret
=
poll
(
&
pollInfo
,
1
,
1000
);
if
(
ret
<
0
)
ERR
(
"poll failed with error %d
\n
"
,
ret
);
else
{
if
(
pollInfo
.
revents
&
POLLIN
)
{
SignalObjectAndWait
(
tcpc
->
onEventAvailable
,
tcpc
->
onEventHandled
,
INFINITE
,
FALSE
);
}
}
}
/* This avoids the tcpc being destroyed before we are done with it */
SetEvent
(
tcpc
->
onEventAvailable
);
return
0
;
}
static
RpcConnection
*
rpcrt4_conn_tcp_alloc
(
void
)
{
RpcConnection_tcp
*
tcpc
;
tcpc
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
RpcConnection_tcp
));
if
(
tcpc
)
tcpc
->
sock
=
-
1
;
if
(
tcpc
==
NULL
)
return
NULL
;
tcpc
->
sock
=
-
1
;
tcpc
->
onEventAvailable
=
NULL
;
tcpc
->
onEventHandled
=
NULL
;
tcpc
->
quit
=
FALSE
;
return
&
tcpc
->
common
;
}
...
...
@@ -470,12 +512,6 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
TRACE
(
"(%s, %s)
\n
"
,
Connection
->
NetworkAddr
,
Connection
->
Endpoint
);
if
(
Connection
->
server
)
{
ERR
(
"ncacn_ip_tcp servers not supported yet
\n
"
);
return
RPC_S_SERVER_UNAVAILABLE
;
}
if
(
tcpc
->
sock
!=
-
1
)
return
RPC_S_OK
;
...
...
@@ -514,14 +550,81 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
continue
;
}
if
(
0
>
connect
(
sock
,
ai_cur
->
ai_addr
,
ai_cur
->
ai_addrlen
)
)
if
(
Connection
->
server
)
{
WARN
(
"connect() failed
\n
"
);
close
(
sock
);
continue
;
HANDLE
thread
=
NULL
;
ret
=
bind
(
sock
,
ai_cur
->
ai_addr
,
ai_cur
->
ai_addrlen
);
if
(
ret
<
0
)
{
WARN
(
"bind failed, error %d
\n
"
,
ret
);
goto
done
;
}
ret
=
listen
(
sock
,
10
);
if
(
ret
<
0
)
{
WARN
(
"listen failed, error %d
\n
"
,
ret
);
goto
done
;
}
/* need a non-blocking socket, otherwise accept() has a potential
* race-condition (poll() says it is readable, connection drops,
* and accept() blocks until the next connection comes...)
*/
ret
=
fcntl
(
sock
,
F_SETFL
,
O_NONBLOCK
);
if
(
ret
<
0
)
{
WARN
(
"couldn't make socket non-blocking, error %d
\n
"
,
ret
);
goto
done
;
}
tcpc
->
onEventAvailable
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
tcpc
->
onEventAvailable
==
NULL
)
{
WARN
(
"creating available event failed, error %lu
\n
"
,
GetLastError
());
goto
done
;
}
tcpc
->
onEventHandled
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
if
(
tcpc
->
onEventHandled
==
NULL
)
{
WARN
(
"creating handled event failed, error %lu
\n
"
,
GetLastError
());
goto
done
;
}
tcpc
->
sock
=
sock
;
thread
=
CreateThread
(
NULL
,
0
,
rpcrt4_tcp_poll_thread
,
tcpc
,
0
,
NULL
);
if
(
thread
==
NULL
)
{
WARN
(
"creating server polling thread failed, error %lu
\n
"
,
GetLastError
());
tcpc
->
sock
=
-
1
;
goto
done
;
}
CloseHandle
(
thread
);
done:
if
(
thread
==
NULL
)
/* ie. we failed somewhere */
{
close
(
sock
);
if
(
tcpc
->
onEventAvailable
!=
NULL
)
{
CloseHandle
(
tcpc
->
onEventAvailable
);
tcpc
->
onEventAvailable
=
NULL
;
}
if
(
tcpc
->
onEventHandled
!=
NULL
)
{
CloseHandle
(
tcpc
->
onEventHandled
);
tcpc
->
onEventHandled
=
NULL
;
}
continue
;
}
}
else
/* it's a client */
{
if
(
0
>
connect
(
sock
,
ai_cur
->
ai_addr
,
ai_cur
->
ai_addrlen
))
{
WARN
(
"connect() failed
\n
"
);
close
(
sock
);
continue
;
}
tcpc
->
sock
=
sock
;
}
tcpc
->
sock
=
sock
;
freeaddrinfo
(
ai
);
TRACE
(
"connected
\n
"
);
...
...
@@ -535,14 +638,29 @@ static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
static
HANDLE
rpcrt4_conn_tcp_get_wait_handle
(
RpcConnection
*
Connection
)
{
assert
(
0
)
;
return
0
;
RpcConnection_tcp
*
tcpc
=
(
RpcConnection_tcp
*
)
Connection
;
return
tcpc
->
onEventAvailable
;
}
static
RPC_STATUS
rpcrt4_conn_tcp_handoff
(
RpcConnection
*
old_conn
,
RpcConnection
*
new_conn
)
{
assert
(
0
);
return
RPC_S_SERVER_UNAVAILABLE
;
int
ret
;
struct
sockaddr_in
address
;
socklen_t
addrsize
;
RpcConnection_tcp
*
server
=
(
RpcConnection_tcp
*
)
old_conn
;
RpcConnection_tcp
*
client
=
(
RpcConnection_tcp
*
)
new_conn
;
addrsize
=
sizeof
(
address
);
ret
=
accept
(
server
->
sock
,
(
struct
sockaddr
*
)
&
address
,
&
addrsize
);
SetEvent
(
server
->
onEventHandled
);
if
(
ret
<
0
)
{
ERR
(
"Failed to accept a TCP connection: error %d
\n
"
,
ret
);
return
RPC_S_SERVER_UNAVAILABLE
;
}
client
->
sock
=
ret
;
TRACE
(
"Accepted a new TCP connection
\n
"
);
return
RPC_S_OK
;
}
static
int
rpcrt4_conn_tcp_read
(
RpcConnection
*
Connection
,
...
...
@@ -568,6 +686,16 @@ static int rpcrt4_conn_tcp_close(RpcConnection *Connection)
RpcConnection_tcp
*
tcpc
=
(
RpcConnection_tcp
*
)
Connection
;
TRACE
(
"%d
\n
"
,
tcpc
->
sock
);
if
(
tcpc
->
onEventAvailable
!=
NULL
)
{
/* it's a server connection */
tcpc
->
quit
=
TRUE
;
WaitForSingleObject
(
tcpc
->
onEventAvailable
,
INFINITE
);
CloseHandle
(
tcpc
->
onEventAvailable
);
CloseHandle
(
tcpc
->
onEventHandled
);
}
if
(
tcpc
->
sock
!=
-
1
)
close
(
tcpc
->
sock
);
tcpc
->
sock
=
-
1
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment