/[rdesktop]/sourceforge.net/trunk/rdesktop/tcp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/tcp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1348 by stargo, Fri Nov 3 23:51:35 2006 UTC revision 1349 by jsorg71, Sat Dec 23 03:23:59 2006 UTC
# Line 2  Line 2 
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - TCP layer     Protocol services - TCP layer
4     Copyright (C) Matthew Chapman 1999-2005     Copyright (C) Matthew Chapman 1999-2005
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #ifndef _WIN32
22  #include <unistd.h>             /* select read write close */  #include <unistd.h>             /* select read write close */
23  #include <sys/socket.h>         /* socket connect setsockopt */  #include <sys/socket.h>         /* socket connect setsockopt */
24  #include <sys/time.h>           /* timeval */  #include <sys/time.h>           /* timeval */
# Line 26  Line 27 
27  #include <netinet/tcp.h>        /* TCP_NODELAY */  #include <netinet/tcp.h>        /* TCP_NODELAY */
28  #include <arpa/inet.h>          /* inet_addr */  #include <arpa/inet.h>          /* inet_addr */
29  #include <errno.h>              /* errno */  #include <errno.h>              /* errno */
30    #endif
31    
32  #include "rdesktop.h"  #include "rdesktop.h"
33    
34    #ifdef _WIN32
35    #define socklen_t int
36    #define TCP_CLOSE(_sck) closesocket(_sck)
37    #define TCP_STRERROR "tcp error"
38    #define TCP_BLOCKS (WSAGetLastError() == WSAEWOULDBLOCK)
39    #else
40    #define TCP_CLOSE(_sck) close(_sck)
41    #define TCP_STRERROR strerror(errno)
42    #define TCP_BLOCKS (errno == EWOULDBLOCK)
43    #endif
44    
45  #ifndef INADDR_NONE  #ifndef INADDR_NONE
46  #define INADDR_NONE ((unsigned long) -1)  #define INADDR_NONE ((unsigned long) -1)
47  #endif  #endif
48    
49  static int sock;  static int g_sock;
50  static struct stream in;  static struct stream g_in;
51  #ifndef WITH_SCARD  #ifndef WITH_SCARD
52  static struct stream out;  static struct stream g_out;
53  #endif  #endif
54  int g_tcp_port_rdp = TCP_PORT_RDP;  int g_tcp_port_rdp = TCP_PORT_RDP;
55    
56    /* wait till socket is ready to write or timeout */
57    static BOOL
58    tcp_can_send(int sck, int millis)
59    {
60            fd_set wfds;
61            struct timeval time;
62            int sel_count;
63    
64            time.tv_sec = millis / 1000;
65            time.tv_usec = (millis * 1000) % 1000000;
66            FD_ZERO(&wfds);
67            FD_SET(sck, &wfds);
68            sel_count = select(sck + 1, 0, &wfds, 0, &time);
69            if (sel_count > 0)
70            {
71                    return True;
72            }
73            return False;
74    }
75    
76  /* Initialise TCP transport data packet */  /* Initialise TCP transport data packet */
77  STREAM  STREAM
78  tcp_init(uint32 maxlen)  tcp_init(uint32 maxlen)
# Line 49  tcp_init(uint32 maxlen) Line 83  tcp_init(uint32 maxlen)
83          scard_lock(SCARD_LOCK_TCP);          scard_lock(SCARD_LOCK_TCP);
84          result = scard_tcp_init();          result = scard_tcp_init();
85  #else  #else
86          result = &out;          result = &g_out;
87  #endif  #endif
88    
89          if (maxlen > result->size)          if (maxlen > result->size)
# Line 78  tcp_send(STREAM s) Line 112  tcp_send(STREAM s)
112  #endif  #endif
113          while (total < length)          while (total < length)
114          {          {
115                  sent = send(sock, s->data + total, length - total, 0);                  sent = send(g_sock, s->data + total, length - total, 0);
116                  if (sent <= 0)                  if (sent <= 0)
117                  {                  {
118                          error("send: %s\n", strerror(errno));                          if (sent == -1 && TCP_BLOCKS)
119                          return;                          {
120                                    tcp_can_send(g_sock, 100);
121                                    sent = 0;
122                            }
123                            else
124                            {
125                                    error("send: %s\n", TCP_STRERROR);
126                                    return;
127                            }
128                  }                  }
   
129                  total += sent;                  total += sent;
130          }          }
131  #ifdef WITH_SCARD  #ifdef WITH_SCARD
# Line 96  tcp_send(STREAM s) Line 137  tcp_send(STREAM s)
137  STREAM  STREAM
138  tcp_recv(STREAM s, uint32 length)  tcp_recv(STREAM s, uint32 length)
139  {  {
140          unsigned int new_length, end_offset, p_offset;          uint32 new_length, end_offset, p_offset;
141          int rcvd = 0;          int rcvd = 0;
142    
143          if (s == NULL)          if (s == NULL)
144          {          {
145                  /* read into "new" stream */                  /* read into "new" stream */
146                  if (length > in.size)                  if (length > g_in.size)
147                  {                  {
148                          in.data = (uint8 *) xrealloc(in.data, length);                          g_in.data = (uint8 *) xrealloc(g_in.data, length);
149                          in.size = length;                          g_in.size = length;
150                  }                  }
151                  in.end = in.p = in.data;                  g_in.end = g_in.p = g_in.data;
152                  s = &in;                  s = &g_in;
153          }          }
154          else          else
155          {          {
# Line 127  tcp_recv(STREAM s, uint32 length) Line 168  tcp_recv(STREAM s, uint32 length)
168    
169          while (length > 0)          while (length > 0)
170          {          {
171                  if (!ui_select(sock))                  if (!ui_select(g_sock))
172                          /* User quit */                          /* User quit */
173                          return NULL;                          return NULL;
174    
175                  rcvd = recv(sock, s->end, length, 0);                  rcvd = recv(g_sock, s->end, length, 0);
176                  if (rcvd < 0)                  if (rcvd < 0)
177                  {                  {
178                          error("recv: %s\n", strerror(errno));                          if (rcvd == -1 && TCP_BLOCKS)
179                          return NULL;                          {
180                                    rcvd = 0;
181                            }
182                            else
183                            {
184                                    error("recv: %s\n", TCP_STRERROR);
185                                    return NULL;
186                            }
187                  }                  }
188                  else if (rcvd == 0)                  else if (rcvd == 0)
189                  {                  {
# Line 154  tcp_recv(STREAM s, uint32 length) Line 202  tcp_recv(STREAM s, uint32 length)
202  BOOL  BOOL
203  tcp_connect(char *server)  tcp_connect(char *server)
204  {  {
205          int true_value = 1;          socklen_t option_len;
206            uint32 option_value;
207    
208  #ifdef IPv6  #ifdef IPv6
209    
# Line 175  tcp_connect(char *server) Line 224  tcp_connect(char *server)
224          }          }
225    
226          ressave = res;          ressave = res;
227          sock = -1;          g_sock = -1;
228          while (res)          while (res)
229          {          {
230                  sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);                  g_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
231                  if (!(sock < 0))                  if (!(g_sock < 0))
232                  {                  {
233                          if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)                          if (connect(g_sock, res->ai_addr, res->ai_addrlen) == 0)
234                                  break;                                  break;
235                          close(sock);                          TCP_CLOSE(g_sock);
236                          sock = -1;                          g_sock = -1;
237                  }                  }
238                  res = res->ai_next;                  res = res->ai_next;
239          }          }
240          freeaddrinfo(ressave);          freeaddrinfo(ressave);
241    
242          if (sock == -1)          if (g_sock == -1)
243          {          {
244                  error("%s: unable to connect\n", server);                  error("%s: unable to connect\n", server);
245                  return False;                  return False;
# Line 211  tcp_connect(char *server) Line 260  tcp_connect(char *server)
260                  return False;                  return False;
261          }          }
262    
263          if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)          if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
264          {          {
265                  error("socket: %s\n", strerror(errno));                  error("socket: %s\n", TCP_STRERROR);
266                  return False;                  return False;
267          }          }
268    
269          servaddr.sin_family = AF_INET;          servaddr.sin_family = AF_INET;
270          servaddr.sin_port = htons(g_tcp_port_rdp);          servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
271    
272          if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)          if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
273          {          {
274                  error("connect: %s\n", strerror(errno));                  error("connect: %s\n", TCP_STRERROR);
275                  close(sock);                  TCP_CLOSE(g_sock);
276                  return False;                  return False;
277          }          }
278    
279  #endif /* IPv6 */  #endif /* IPv6 */
280    
281          setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));          option_value = 1;
282            option_len = sizeof(option_value);
283            setsockopt(g_sock, IPPROTO_TCP, TCP_NODELAY, (void *) &option_value, option_len);
284            /* receive buffer must be a least 16 K */
285            if (getsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value, &option_len) == 0)
286            {
287                    if (option_value < (1024 * 16))
288                    {
289                            option_value = 1024 * 16;
290                            option_len = sizeof(option_value);
291                            setsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value, option_len);
292                    }
293            }
294    
295          in.size = 4096;          g_in.size = 4096;
296          in.data = (uint8 *) xmalloc(in.size);          g_in.data = (uint8 *) xmalloc(g_in.size);
297    
298  #ifdef WITH_SCARD  #ifdef WITH_SCARD
299          scard_tcp_connect();          scard_tcp_connect();
300  #else  #else
301          out.size = 4096;          g_out.size = 4096;
302          out.data = (uint8 *) xmalloc(out.size);          g_out.data = (uint8 *) xmalloc(g_out.size);
303  #endif  #endif
304    
305          return True;          return True;
# Line 248  tcp_connect(char *server) Line 309  tcp_connect(char *server)
309  void  void
310  tcp_disconnect(void)  tcp_disconnect(void)
311  {  {
312          close(sock);          TCP_CLOSE(g_sock);
313  }  }
314    
315  char *  char *
# Line 257  tcp_get_address() Line 318  tcp_get_address()
318          static char ipaddr[32];          static char ipaddr[32];
319          struct sockaddr_in sockaddr;          struct sockaddr_in sockaddr;
320          socklen_t len = sizeof(sockaddr);          socklen_t len = sizeof(sockaddr);
321          if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)          if (getsockname(g_sock, (struct sockaddr *) &sockaddr, &len) == 0)
322          {          {
323                  unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;                  uint8 *ip = (uint8 *) &sockaddr.sin_addr;
324                  sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);                  sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
325          }          }
326          else          else
# Line 272  tcp_get_address() Line 333  tcp_get_address()
333  void  void
334  tcp_reset_state(void)  tcp_reset_state(void)
335  {  {
336          sock = -1;              /* reset socket */          g_sock = -1;            /* reset socket */
337    
338          /* Clear the incoming stream */          /* Clear the incoming stream */
339          if (in.data != NULL)          if (g_in.data != NULL)
340                  xfree(in.data);                  xfree(g_in.data);
341          in.p = NULL;          g_in.p = NULL;
342          in.end = NULL;          g_in.end = NULL;
343          in.data = NULL;          g_in.data = NULL;
344          in.size = 0;          g_in.size = 0;
345          in.iso_hdr = NULL;          g_in.iso_hdr = NULL;
346          in.mcs_hdr = NULL;          g_in.mcs_hdr = NULL;
347          in.sec_hdr = NULL;          g_in.sec_hdr = NULL;
348          in.rdp_hdr = NULL;          g_in.rdp_hdr = NULL;
349          in.channel_hdr = NULL;          g_in.channel_hdr = NULL;
350    
351          /* Clear the outgoing stream(s) */          /* Clear the outgoing stream(s) */
352  #ifdef WITH_SCARD  #ifdef WITH_SCARD
353          scard_tcp_reset_state();          scard_tcp_reset_state();
354  #else  #else
355          if (out.data != NULL)          if (g_out.data != NULL)
356                  xfree(out.data);                  xfree(g_out.data);
357          out.p = NULL;          g_out.p = NULL;
358          out.end = NULL;          g_out.end = NULL;
359          out.data = NULL;          g_out.data = NULL;
360          out.size = 0;          g_out.size = 0;
361          out.iso_hdr = NULL;          g_out.iso_hdr = NULL;
362          out.mcs_hdr = NULL;          g_out.mcs_hdr = NULL;
363          out.sec_hdr = NULL;          g_out.sec_hdr = NULL;
364          out.rdp_hdr = NULL;          g_out.rdp_hdr = NULL;
365          out.channel_hdr = NULL;          g_out.channel_hdr = NULL;
366  #endif  #endif
367  }  }

Legend:
Removed from v.1348  
changed lines
  Added in v.1349

  ViewVC Help
Powered by ViewVC 1.1.26