ReactOS  0.4.14-dev-49-gfb4591c
tcp.c File Reference
#include "rdesktop.h"
#include <winsock2.h>
Include dependency graph for tcp.c:

Go to the source code of this file.

Macros

#define INADDR_NONE   ((unsigned long) -1)
 

Typedefs

typedef int socklen_t
 

Functions

STREAM tcp_init (RDPCLIENT *This, uint32 maxlen)
 
BOOL tcp_send (RDPCLIENT *This, STREAM s)
 
STREAM tcp_recv (RDPCLIENT *This, STREAM s, uint32 length)
 
BOOL tcp_connect (RDPCLIENT *This, char *server)
 
BOOL tcp_disconnect (RDPCLIENT *This)
 
wchar_ttcp_get_address (RDPCLIENT *This)
 
void tcp_reset_state (RDPCLIENT *This)
 

Macro Definition Documentation

◆ INADDR_NONE

#define INADDR_NONE   ((unsigned long) -1)

Definition at line 38 of file tcp.c.

Typedef Documentation

◆ socklen_t

typedef int socklen_t

Definition at line 35 of file tcp.c.

Function Documentation

◆ tcp_connect()

BOOL tcp_connect ( RDPCLIENT This,
char server 
)

Definition at line 205 of file tcp.c.

206 {
207  int true_value = 1;
208 
209 #ifdef IPv6
210 
211  int n;
212  struct addrinfo hints, *res, *ressave;
213  char tcp_port_rdp_s[10];
214 
215  snprintf(tcp_port_rdp_s, 10, "%d", This->tcp_port_rdp);
216 
217  memset(&hints, 0, sizeof(struct addrinfo));
218  hints.ai_family = AF_UNSPEC;
219  hints.ai_socktype = SOCK_STREAM;
220 
221  if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res)))
222  {
223  error("getaddrinfo: %s\n", gai_strerror(n));
224  return False;
225  }
226 
227  ressave = res;
228  This->tcp.sock = -1;
229  while (res)
230  {
231  This->tcp.sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
232  if (!(This->tcp.sock < 0))
233  {
234  if (connect(This->tcp.sock, res->ai_addr, res->ai_addrlen) == 0)
235  break;
236  close(This->tcp.sock);
237  This->tcp.sock = -1;
238  }
239  res = res->ai_next;
240  }
241  freeaddrinfo(ressave);
242 
243  if (This->tcp.sock == -1)
244  {
245  error("%s: unable to connect\n", server);
246  return False;
247  }
248 
249 #else /* no IPv6 support */
250 
251  struct hostent *nslookup;
252  struct sockaddr_in servaddr;
253 
254  if ((nslookup = gethostbyname(server)) != NULL)
255  {
256  memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
257  }
258  else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
259  {
260  error("%s: unable to resolve host\n", server);
261  This->disconnect_reason = 260;
262  return False;
263  }
264 
265  if ((This->tcp.sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
266  {
267  // error("socket: %s\n", strerror(errno)); // EOF
268  return False;
269  }
270 
271  servaddr.sin_family = AF_INET;
272  servaddr.sin_port = htons(This->tcp_port_rdp);
273 
274  // TODO: apply connection timeout here
275 
276  if (connect(This->tcp.sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
277  {
278  // error("connect: %s\n", strerror(errno)); // EOF
279  This->disconnect_reason = 516;
280  closesocket(This->tcp.sock);
281  return False;
282  }
283 
284 #endif /* IPv6 */
285 
286  setsockopt(This->tcp.sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
287 
288  This->tcp.in.size = 4096;
289  This->tcp.in.data = (uint8 *) malloc(This->tcp.in.size);
290 
291  if(This->tcp.in.data == NULL)
292  {
293  This->disconnect_reason = 262;
294  return False;
295  }
296 
297  This->tcp.out.size = 4096;
298  This->tcp.out.data = (uint8 *) malloc(This->tcp.out.size);
299 
300  if(This->tcp.out.data == NULL)
301  {
302  This->disconnect_reason = 262;
303  return False;
304  }
305 
306  return True;
307 }
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
static rfbScreenInfoPtr server
Definition: vnc.c:74
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
#define freeaddrinfo
Definition: wspiapi.h:46
#define inet_addr(cp)
Definition: inet.h:98
#define error(str)
Definition: mkdosfs.c:1605
GLdouble n
Definition: glext.h:7729
#define snprintf
Definition: wintirpc.h:48
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
#define TCP_NODELAY
Definition: tcpdef.h:117
#define closesocket
Definition: main.c:39
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
smooth NULL
Definition: ftsmooth.c:416
#define AF_UNSPEC
Definition: winsock.h:344
#define True
Definition: types.h:24
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
#define False
Definition: types.h:25
unsigned char uint8
Definition: types.h:28
#define gai_strerror
Definition: ws2tcpip.h:521
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define close
Definition: acwin.h:98
GLuint res
Definition: glext.h:9613
#define INADDR_NONE
Definition: tcp.c:38
#define AF_INET
Definition: tcpip.h:117
#define malloc
Definition: debug_ros.c:4
#define SOCK_STREAM
Definition: tcpip.h:118
#define htons(x)
Definition: module.h:213
#define memset(x, y, z)
Definition: compat.h:39
#define getaddrinfo
Definition: wspiapi.h:44

◆ tcp_disconnect()

BOOL tcp_disconnect ( RDPCLIENT This)

Definition at line 311 of file tcp.c.

312 {
313  closesocket(This->tcp.sock);
314  return True;
315 }
#define closesocket
Definition: main.c:39
#define True
Definition: types.h:24

◆ tcp_get_address()

wchar_t* tcp_get_address ( RDPCLIENT This)

Definition at line 318 of file tcp.c.

319 {
320 #if 0
321  static char ipaddr[32];
322  struct sockaddr_in sockaddr;
323  socklen_t len = sizeof(sockaddr);
324  if (getsockname(This->tcp.sock, (struct sockaddr *) &sockaddr, &len) == 0)
325  {
326  unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;
327  sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
328  }
329  else
330  strcpy(ipaddr, "127.0.0.1");
331  return ipaddr;
332 #endif
333  return NULL; // TODO
334 }
#define sprintf(buf, format,...)
Definition: sprintf.c:55
smooth NULL
Definition: ftsmooth.c:416
Definition: dhcpd.h:61
int socklen_t
Definition: tcp.c:35
GLenum GLsizei len
Definition: glext.h:6722
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213

◆ tcp_init()

STREAM tcp_init ( RDPCLIENT This,
uint32  maxlen 
)

Definition at line 43 of file tcp.c.

44 {
45  if (maxlen > This->tcp.out.size)
46  {
47  void * p;
48 
49  p = realloc(This->tcp.out.data, maxlen);
50 
51  if (p == NULL)
52  {
53  This->disconnect_reason = 262;
54  return NULL;
55  }
56 
57  This->tcp.out.data = (uint8 *)p;
58  This->tcp.out.size = maxlen;
59  }
60 
61  This->tcp.out.p = This->tcp.out.data;
62  This->tcp.out.end = This->tcp.out.data + This->tcp.out.size;
63  return &This->tcp.out;
64 }
#define realloc
Definition: debug_ros.c:6
smooth NULL
Definition: ftsmooth.c:416
unsigned char uint8
Definition: types.h:28
GLfloat GLfloat p
Definition: glext.h:8902

◆ tcp_recv()

STREAM tcp_recv ( RDPCLIENT This,
STREAM  s,
uint32  length 
)

Definition at line 110 of file tcp.c.

111 {
112  unsigned int new_length, end_offset, p_offset;
113  DWORD rcvd = 0;
114 
115  if (s == NULL)
116  {
117  /* read into "new" stream */
118  if (length > This->tcp.in.size)
119  {
120  void * p = realloc(This->tcp.in.data, length);
121 
122  if(p == NULL)
123  {
124  This->disconnect_reason = 262;
125  return NULL;
126  }
127 
128  This->tcp.in.data = (uint8 *) p;
129  This->tcp.in.size = length;
130  }
131  This->tcp.in.end = This->tcp.in.p = This->tcp.in.data;
132  s = &This->tcp.in;
133  }
134  else
135  {
136  /* append to existing stream */
137  new_length = (unsigned int)(s->end - s->data) + length;
138  if (new_length > s->size)
139  {
140  void * p = realloc(s->data, new_length);
141 
142  if(p == NULL)
143  {
144  This->disconnect_reason = 262;
145  return NULL;
146  }
147 
148  p_offset = (unsigned int)(s->p - s->data);
149  end_offset = (unsigned int)(s->end - s->data);
150  s->data = (uint8 *) p;
151  s->size = new_length;
152  s->p = s->data + p_offset;
153  s->end = s->data + end_offset;
154  }
155  }
156 
157  while (length > 0)
158  {
160  memset(&overlapped, 0, sizeof(overlapped));
161 
162  if (!ui_select(This, This->tcp.sock))
163  /* User quit */
164  return NULL;
165 
166  ReadFile((HANDLE)This->tcp.sock, s->end, length, NULL, &overlapped);
167 
168  switch(WaitForSingleObjectEx((HANDLE)This->tcp.sock, INFINITE, TRUE))
169  {
170  /* Success */
171  case WAIT_OBJECT_0:
172  break;
173 
174  /* Timeout or error */
175  case WAIT_TIMEOUT:
176  default:
177  This->disconnect_reason = 1028;
178 
179  /* Aborted, must disconnect ASAP */
180  case WAIT_IO_COMPLETION:
181  CancelIo((HANDLE)This->tcp.sock);
182  break;
183  }
184 
185  /* Wait for completion. We could hang here, but we shouldn't */
186  if(!GetOverlappedResult((HANDLE)This->tcp.sock, &overlapped, &rcvd, TRUE))
187  return False;
188 
189  if (rcvd == 0)
190  {
191  error("Connection closed\n");
192  This->disconnect_reason = 2308;
193  return NULL;
194  }
195 
196  s->end += rcvd;
197  length -= rcvd;
198  }
199 
200  return s;
201 }
#define realloc
Definition: debug_ros.c:6
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define TRUE
Definition: types.h:120
#define error(str)
Definition: mkdosfs.c:1605
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
smooth NULL
Definition: ftsmooth.c:416
#define WAIT_IO_COMPLETION
Definition: winbase.h:392
#define False
Definition: types.h:25
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char uint8
Definition: types.h:28
#define WAIT_TIMEOUT
Definition: dderror.h:14
GLdouble s
Definition: gl.h:2039
int ui_select(int rdp_socket)
Definition: uimain.c:164
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:82
GLfloat GLfloat p
Definition: glext.h:8902
#define INFINITE
Definition: serial.h:102
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
#define memset(x, y, z)
Definition: compat.h:39
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

◆ tcp_reset_state()

void tcp_reset_state ( RDPCLIENT This)

Definition at line 339 of file tcp.c.

340 {
341  This->tcp.sock = -1; /* reset socket */
342 
343  /* Clear the incoming stream */
344  if (This->tcp.in.data != NULL)
345  free(This->tcp.in.data);
346  This->tcp.in.p = NULL;
347  This->tcp.in.end = NULL;
348  This->tcp.in.data = NULL;
349  This->tcp.in.size = 0;
350  This->tcp.in.iso_hdr = NULL;
351  This->tcp.in.mcs_hdr = NULL;
352  This->tcp.in.sec_hdr = NULL;
353  This->tcp.in.rdp_hdr = NULL;
354  This->tcp.in.channel_hdr = NULL;
355 
356  /* Clear the outgoing stream */
357  if (This->tcp.out.data != NULL)
358  free(This->tcp.out.data);
359  This->tcp.out.p = NULL;
360  This->tcp.out.end = NULL;
361  This->tcp.out.data = NULL;
362  This->tcp.out.size = 0;
363  This->tcp.out.iso_hdr = NULL;
364  This->tcp.out.mcs_hdr = NULL;
365  This->tcp.out.sec_hdr = NULL;
366  This->tcp.out.rdp_hdr = NULL;
367  This->tcp.out.channel_hdr = NULL;
368 }
#define free
Definition: debug_ros.c:5
smooth NULL
Definition: ftsmooth.c:416

◆ tcp_send()

BOOL tcp_send ( RDPCLIENT This,
STREAM  s 
)

Definition at line 68 of file tcp.c.

69 {
70  int length = (int)(s->end - s->data);
71  int total = 0;
72  DWORD sent;
73 
75  memset(&overlapped, 0, sizeof(overlapped));
76 
77  while (total < length)
78  {
79  WriteFile((HANDLE)This->tcp.sock, s->data + total, length - total, NULL, &overlapped);
80 
81  switch(WaitForSingleObjectEx((HANDLE)This->tcp.sock, INFINITE, TRUE))
82  {
83  /* Success */
84  case WAIT_OBJECT_0:
85  break;
86 
87  /* Timeout or error */
88  case WAIT_TIMEOUT:
89  default:
90  This->disconnect_reason = 772;
91 
92  /* Aborted, must disconnect ASAP */
93  case WAIT_IO_COMPLETION:
94  CancelIo((HANDLE)This->tcp.sock);
95  break;
96  }
97 
98  /* Wait for completion. We could hang here, but we shouldn't */
99  if(!GetOverlappedResult((HANDLE)This->tcp.sock, &overlapped, &sent, TRUE))
100  return False;
101 
102  total += sent;
103  }
104 
105  return True;
106 }
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define TRUE
Definition: types.h:120
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
BOOL WINAPI CancelIo(IN HANDLE hFile)
Definition: deviceio.c:290
smooth NULL
Definition: ftsmooth.c:416
#define WAIT_IO_COMPLETION
Definition: winbase.h:392
#define True
Definition: types.h:24
#define False
Definition: types.h:25
#define WAIT_OBJECT_0
Definition: winbase.h:387
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WAIT_TIMEOUT
Definition: dderror.h:14
Definition: msg.h:34
GLdouble s
Definition: gl.h:2039
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:82
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31