/[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 977 by astrand, Mon Aug 8 19:15:57 2005 UTC revision 1372 by jsorg71, Mon Jan 8 04:47:06 2007 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
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-2007
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  static struct stream out;  #ifndef WITH_SCARD
52    static struct stream g_out;
53    #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 RD_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)
79  {  {
80          if (maxlen > out.size)          STREAM result = NULL;
81    
82    #ifdef WITH_SCARD
83            scard_lock(SCARD_LOCK_TCP);
84            result = scard_tcp_init();
85    #else
86            result = &g_out;
87    #endif
88    
89            if (maxlen > result->size)
90          {          {
91                  out.data = (uint8 *) xrealloc(out.data, maxlen);                  result->data = (uint8 *) xrealloc(result->data, maxlen);
92                  out.size = maxlen;                  result->size = maxlen;
93          }          }
94    
95          out.p = out.data;          result->p = result->data;
96          out.end = out.data + out.size;          result->end = result->data + result->size;
97          return &out;  #ifdef WITH_SCARD
98            scard_unlock(SCARD_LOCK_TCP);
99    #endif
100            return result;
101  }  }
102    
103  /* Send TCP transport data packet */  /* Send TCP transport data packet */
# Line 59  tcp_send(STREAM s) Line 107  tcp_send(STREAM s)
107          int length = s->end - s->data;          int length = s->end - s->data;
108          int sent, total = 0;          int sent, total = 0;
109    
110    #ifdef WITH_SCARD
111            scard_lock(SCARD_LOCK_TCP);
112    #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
132            scard_unlock(SCARD_LOCK_TCP);
133    #endif
134  }  }
135    
136  /* Receive a message on the TCP layer */  /* Receive a message on the TCP layer */
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 107  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 131  tcp_recv(STREAM s, uint32 length) Line 199  tcp_recv(STREAM s, uint32 length)
199  }  }
200    
201  /* Establish a connection on the TCP layer */  /* Establish a connection on the TCP layer */
202  BOOL  RD_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 155  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 191  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,
292                                       option_len);
293                    }
294            }
295    
296          in.size = 4096;          g_in.size = 4096;
297          in.data = (uint8 *) xmalloc(in.size);          g_in.data = (uint8 *) xmalloc(g_in.size);
298    
299          out.size = 4096;  #ifdef WITH_SCARD
300          out.data = (uint8 *) xmalloc(out.size);          scard_tcp_connect();
301    #else
302            g_out.size = 4096;
303            g_out.data = (uint8 *) xmalloc(g_out.size);
304    #endif
305    
306          return True;          return True;
307  }  }
# Line 224  tcp_connect(char *server) Line 310  tcp_connect(char *server)
310  void  void
311  tcp_disconnect(void)  tcp_disconnect(void)
312  {  {
313          close(sock);          TCP_CLOSE(g_sock);
314  }  }
315    
316  char *  char *
# Line 233  tcp_get_address() Line 319  tcp_get_address()
319          static char ipaddr[32];          static char ipaddr[32];
320          struct sockaddr_in sockaddr;          struct sockaddr_in sockaddr;
321          socklen_t len = sizeof(sockaddr);          socklen_t len = sizeof(sockaddr);
322          if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)          if (getsockname(g_sock, (struct sockaddr *) &sockaddr, &len) == 0)
323          {          {
324                  unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;                  uint8 *ip = (uint8 *) & sockaddr.sin_addr;
325                  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]);
326          }          }
327          else          else
# Line 248  tcp_get_address() Line 334  tcp_get_address()
334  void  void
335  tcp_reset_state(void)  tcp_reset_state(void)
336  {  {
337          sock = -1;              /* reset socket */          g_sock = -1;            /* reset socket */
338    
339          /* Clear the incoming stream */          /* Clear the incoming stream */
340          if (in.data != NULL)          if (g_in.data != NULL)
341                  xfree(in.data);                  xfree(g_in.data);
342          in.p = NULL;          g_in.p = NULL;
343          in.end = NULL;          g_in.end = NULL;
344          in.data = NULL;          g_in.data = NULL;
345          in.size = 0;          g_in.size = 0;
346          in.iso_hdr = NULL;          g_in.iso_hdr = NULL;
347          in.mcs_hdr = NULL;          g_in.mcs_hdr = NULL;
348          in.sec_hdr = NULL;          g_in.sec_hdr = NULL;
349          in.rdp_hdr = NULL;          g_in.rdp_hdr = NULL;
350          in.channel_hdr = NULL;          g_in.channel_hdr = NULL;
351    
352          /* Clear the outgoing stream */          /* Clear the outgoing stream(s) */
353          if (out.data != NULL)  #ifdef WITH_SCARD
354                  xfree(out.data);          scard_tcp_reset_state();
355          out.p = NULL;  #else
356          out.end = NULL;          if (g_out.data != NULL)
357          out.data = NULL;                  xfree(g_out.data);
358          out.size = 0;          g_out.p = NULL;
359          out.iso_hdr = NULL;          g_out.end = NULL;
360          out.mcs_hdr = NULL;          g_out.data = NULL;
361          out.sec_hdr = NULL;          g_out.size = 0;
362          out.rdp_hdr = NULL;          g_out.iso_hdr = NULL;
363          out.channel_hdr = NULL;          g_out.mcs_hdr = NULL;
364            g_out.sec_hdr = NULL;
365            g_out.rdp_hdr = NULL;
366            g_out.channel_hdr = NULL;
367    #endif
368  }  }

Legend:
Removed from v.977  
changed lines
  Added in v.1372

  ViewVC Help
Powered by ViewVC 1.1.26