ReactOS 0.4.15-dev-8028-g8e799e2
skelserver.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS simple TCP/IP services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/services/tcpsvcs/skelserver.c
5 * PURPOSE: Sets up a server and listens for connections
6 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@gmail.com>
7 *
8 */
9
10#include "tcpsvcs.h"
11
12#define BUF 1024
13
14static SOCKET
16{
19 BOOL bSetup = FALSE;
20
22 if (sock != INVALID_SOCKET)
23 {
24 ZeroMemory(&server, sizeof(SOCKADDR_IN));
25 server.sin_family = AF_INET;
26 server.sin_addr.s_addr = htonl(INADDR_ANY);
27 server.sin_port = Port;
28
29 if (bind(sock, (SOCKADDR*)&server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
30 {
32 {
33 bSetup = TRUE;
34 }
35 else
36 {
37 LogEvent(L"listen() failed", WSAGetLastError(), 0, LOG_ERROR);
38 }
39 }
40 else
41 {
42 LogEvent(L"bind() failed", WSAGetLastError(), 0, LOG_ERROR);
43 }
44 }
45 else
46 {
47 LogEvent(L"socket() failed", WSAGetLastError(), 0, LOG_ERROR);
48 }
49
50 return bSetup ? sock : INVALID_SOCKET;
51}
52
53
54static VOID
55AcceptConnections(SOCKET listeningSocket,
56 LPTHREAD_START_ROUTINE lpService,
58{
62 TIMEVAL timeVal;
63 FD_SET readFD;
64 WCHAR logBuf[256];
65 INT timeOut = 2000;
66
67 timeVal.tv_sec = timeOut / 1000;
68 timeVal.tv_usec = timeOut % 1000;
69
70 while (!bShutdown)
71 {
72 INT selRet = 0;
73
74 FD_ZERO(&readFD);
75 FD_SET(listeningSocket, &readFD);
76
77 selRet = select(0, &readFD, NULL, NULL, &timeVal);
78 if (selRet > 0)
79 {
80 if (!bShutdown || FD_ISSET(listeningSocket, &readFD))
81 {
82 INT addrSize = sizeof(SOCKADDR_IN);
83
84 sock = accept(listeningSocket, (SOCKADDR*)&client, &addrSize);
85 if (sock != INVALID_SOCKET)
86 {
87 swprintf(logBuf,
88 L"Accepted connection to %s server from %S:%d",
89 lpName,
90 inet_ntoa(client.sin_addr),
91 ntohs(client.sin_port));
92 LogEvent(logBuf, 0, 0, LOG_FILE);
93
94 swprintf(logBuf, L"Creating worker thread for %s", lpName);
95 LogEvent(logBuf, 0, 0, LOG_FILE);
96
97 if (!bShutdown)
98 {
99 hThread = CreateThread(0, 0, lpService, (void*)sock, 0, NULL);
100 if (hThread != NULL)
101 {
103 }
104 else
105 {
106 swprintf(logBuf, L"Failed to start worker thread for the %s server",
107 lpName);
108 LogEvent(logBuf, 0, 0, LOG_FILE);
109 }
110 }
111 }
112 else
113 {
114 LogEvent(L"accept failed", WSAGetLastError(), 0, LOG_ERROR);
115 }
116 }
117 }
118 else if (selRet == SOCKET_ERROR)
119 {
120 LogEvent(L"select failed", WSAGetLastError(), 0, LOG_ERROR);
121 }
122 }
123}
124
125BOOL
127 BOOL bRec)
128{
129 WCHAR logBuf[256];
130
131 /* Disallow any further data sends. This will tell the other side
132 that we want to go away now. If we skip this step, we don't
133 shut the connection down nicely. */
135 {
136 LogEvent(L"Error in shutdown()", WSAGetLastError(), 0, LOG_ERROR);
137 return FALSE;
138 }
139
140 /* Receive any extra data still sitting on the socket
141 before we close it */
142 if (bRec)
143 {
144 CHAR readBuffer[BUF];
145 INT ret;
146
147 do
148 {
149 ret = recv(sock, readBuffer, BUF, 0);
150 if (ret >= 0)
151 {
152 swprintf(logBuf, L"FYI, received %d unexpected bytes during shutdown", ret);
153 LogEvent(logBuf, 0, 0, LOG_FILE);
154 }
155 } while (ret > 0);
156 }
157
159
160 return TRUE;
161}
162
163
166{
167 SOCKET listeningSocket;
168 PSERVICES pServices;
169 TCHAR logBuf[256];
170
171 pServices = (PSERVICES)lpParam;
172
173 swprintf(logBuf, L"Starting %s server", pServices->lpName);
174 LogEvent(logBuf, 0, 0, LOG_FILE);
175
176 if (!bShutdown)
177 {
178 listeningSocket = SetUpListener(htons(pServices->Port));
179 if (!bShutdown && listeningSocket != INVALID_SOCKET)
180 {
181 swprintf(logBuf,
182 L"%s is waiting for connections on port %d",
183 pServices->lpName,
184 pServices->Port);
185 LogEvent(logBuf, 0, 0, LOG_FILE);
186
187 AcceptConnections(listeningSocket, pServices->lpService, pServices->lpName);
188 }
189 else
190 {
191 LogEvent(L"Socket error when setting up listener", 0, 0, LOG_FILE);
192 }
193 }
194
195 swprintf(logBuf, L"Exiting %s thread", pServices->lpName);
196 LogEvent(logBuf, 0, 0, LOG_FILE);
197 ExitThread(0);
198}
VOID LogEvent(LPCWSTR lpMsg, DWORD errNum, DWORD exitCode, UINT flags)
Definition: log.c:196
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define swprintf
Definition: precomp.h:40
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
CPPORT Port[4]
Definition: headless.c:35
#define INADDR_ANY
Definition: inet.h:53
#define inet_ntoa(addr)
Definition: inet.h:100
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
#define htonl(x)
Definition: module.h:214
#define closesocket
Definition: ncftp.h:477
HANDLE hThread
Definition: wizard.c:28
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
static FILE * client
Definition: client.c:41
static SOCKET SetUpListener(USHORT Port)
Definition: skelserver.c:15
#define BUF
Definition: skelserver.c:12
BOOL ShutdownConnection(SOCKET sock, BOOL bRec)
Definition: skelserver.c:126
DWORD WINAPI StartServer(LPVOID lpParam)
Definition: skelserver.c:165
static VOID AcceptConnections(SOCKET listeningSocket, LPTHREAD_START_ROUTINE lpService, LPWSTR lpName)
Definition: skelserver.c:55
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: jssnprintf.c:29
USHORT Port
Definition: tcpsvcs.h:33
LPWSTR lpName
Definition: tcpsvcs.h:34
LPTHREAD_START_ROUTINE lpService
Definition: tcpsvcs.h:35
Definition: winsock.h:66
Definition: tcpcore.h:1455
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
volatile BOOL bShutdown
Definition: tcpsvcs.c:16
struct _Services * PSERVICES
#define LOG_ERROR
Definition: tcpsvcs.h:16
int32_t INT
Definition: typedefs.h:58
static rfbScreenInfoPtr server
Definition: vnc.c:74
int ret
#define ZeroMemory
Definition: winbase.h:1712
_In_ LPCSTR lpName
Definition: winbase.h:2789
DWORD(WINAPI * LPTHREAD_START_ROUTINE)(LPVOID)
Definition: winbase.h:729
#define WINAPI
Definition: msvc.h:6
#define SOMAXCONN
Definition: winsock.h:399
#define FD_ISSET(fd, set)
Definition: winsock.h:100
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112
#define FD_ZERO(set)
Definition: winsock.h:96
#define INVALID_SOCKET
Definition: winsock.h:332
struct sockaddr_in SOCKADDR_IN
Definition: winsock.h:487
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define SD_SEND
Definition: winsock.h:55
#define FD_SET(fd, set)
Definition: winsock.h:89
char TCHAR
Definition: xmlstorage.h:189
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175