/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/tcp.c

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

revision 963 by astrand, Wed Aug 3 10:56:16 2005 UTC revision 1475 by jsorg71, Fri Jul 11 03:51:23 2008 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-2008
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;  #ifdef WITH_SCARD
50  static struct stream in;  #define STREAM_COUNT 8
51  static struct stream out;  #else
52    #define STREAM_COUNT 1
53    #endif
54    
55    static int g_sock;
56    static struct stream g_in;
57    static struct stream g_out[STREAM_COUNT];
58  int g_tcp_port_rdp = TCP_PORT_RDP;  int g_tcp_port_rdp = TCP_PORT_RDP;
59    
60    /* wait till socket is ready to write or timeout */
61    static RD_BOOL
62    tcp_can_send(int sck, int millis)
63    {
64            fd_set wfds;
65            struct timeval time;
66            int sel_count;
67    
68            time.tv_sec = millis / 1000;
69            time.tv_usec = (millis * 1000) % 1000000;
70            FD_ZERO(&wfds);
71            FD_SET(sck, &wfds);
72            sel_count = select(sck + 1, 0, &wfds, 0, &time);
73            if (sel_count > 0)
74            {
75                    return True;
76            }
77            return False;
78    }
79    
80  /* Initialise TCP transport data packet */  /* Initialise TCP transport data packet */
81  STREAM  STREAM
82  tcp_init(uint32 maxlen)  tcp_init(uint32 maxlen)
83  {  {
84          if (maxlen > out.size)          static int cur_stream_id = 0;
85            STREAM result = NULL;
86    
87    #ifdef WITH_SCARD
88            scard_lock(SCARD_LOCK_TCP);
89    #endif
90            result = &g_out[cur_stream_id];
91            cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
92    
93            if (maxlen > result->size)
94          {          {
95                  out.data = (uint8 *) xrealloc(out.data, maxlen);                  result->data = (uint8 *) xrealloc(result->data, maxlen);
96                  out.size = maxlen;                  result->size = maxlen;
97          }          }
98    
99          out.p = out.data;          result->p = result->data;
100          out.end = out.data + out.size;          result->end = result->data + result->size;
101          return &out;  #ifdef WITH_SCARD
102            scard_unlock(SCARD_LOCK_TCP);
103    #endif
104            return result;
105  }  }
106    
107  /* Send TCP transport data packet */  /* Send TCP transport data packet */
# Line 59  tcp_send(STREAM s) Line 111  tcp_send(STREAM s)
111          int length = s->end - s->data;          int length = s->end - s->data;
112          int sent, total = 0;          int sent, total = 0;
113    
114    #ifdef WITH_SCARD
115            scard_lock(SCARD_LOCK_TCP);
116    #endif
117          while (total < length)          while (total < length)
118          {          {
119                  sent = send(sock, s->data + total, length - total, 0);                  sent = send(g_sock, s->data + total, length - total, 0);
120                  if (sent <= 0)                  if (sent <= 0)
121                  {                  {
122                          error("send: %s\n", strerror(errno));                          if (sent == -1 && TCP_BLOCKS)
123                          return;                          {
124                                    tcp_can_send(g_sock, 100);
125                                    sent = 0;
126                            }
127                            else
128                            {
129                                    error("send: %s\n", TCP_STRERROR);
130                                    return;
131                            }
132                  }                  }
   
133                  total += sent;                  total += sent;
134          }          }
135    #ifdef WITH_SCARD
136            scard_unlock(SCARD_LOCK_TCP);
137    #endif
138  }  }
139    
140  /* Receive a message on the TCP layer */  /* Receive a message on the TCP layer */
141  STREAM  STREAM
142  tcp_recv(STREAM s, uint32 length)  tcp_recv(STREAM s, uint32 length)
143  {  {
144          unsigned int new_length, end_offset, p_offset;          uint32 new_length, end_offset, p_offset;
145          int rcvd = 0;          int rcvd = 0;
146    
147          if (s == NULL)          if (s == NULL)
148          {          {
149                  /* read into "new" stream */                  /* read into "new" stream */
150                  if (length > in.size)                  if (length > g_in.size)
151                  {                  {
152                          in.data = (uint8 *) xrealloc(in.data, length);                          g_in.data = (uint8 *) xrealloc(g_in.data, length);
153                          in.size = length;                          g_in.size = length;
154                  }                  }
155                  in.end = in.p = in.data;                  g_in.end = g_in.p = g_in.data;
156                  s = &in;                  s = &g_in;
157          }          }
158          else          else
159          {          {
# Line 107  tcp_recv(STREAM s, uint32 length) Line 172  tcp_recv(STREAM s, uint32 length)
172    
173          while (length > 0)          while (length > 0)
174          {          {
175                  if (!ui_select(sock))                  if (!ui_select(g_sock))
176                          /* User quit */                          /* User quit */
177                          return NULL;                          return NULL;
178    
179                  rcvd = recv(sock, s->end, length, 0);                  rcvd = recv(g_sock, s->end, length, 0);
180                  if (rcvd < 0)                  if (rcvd < 0)
181                  {                  {
182                          error("recv: %s\n", strerror(errno));                          if (rcvd == -1 && TCP_BLOCKS)
183                          return NULL;                          {
184                                    rcvd = 0;
185                            }
186                            else
187                            {
188                                    error("recv: %s\n", TCP_STRERROR);
189                                    return NULL;
190                            }
191                  }                  }
192                  else if (rcvd == 0)                  else if (rcvd == 0)
193                  {                  {
# Line 131  tcp_recv(STREAM s, uint32 length) Line 203  tcp_recv(STREAM s, uint32 length)
203  }  }
204    
205  /* Establish a connection on the TCP layer */  /* Establish a connection on the TCP layer */
206  BOOL  RD_BOOL
207  tcp_connect(char *server)  tcp_connect(char *server)
208  {  {
209          int true_value = 1;          socklen_t option_len;
210            uint32 option_value;
211            int i;
212    
213  #ifdef IPv6  #ifdef IPv6
214    
# Line 155  tcp_connect(char *server) Line 229  tcp_connect(char *server)
229          }          }
230    
231          ressave = res;          ressave = res;
232          sock = -1;          g_sock = -1;
233          while (res)          while (res)
234          {          {
235                  sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);                  g_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
236                  if (!(sock < 0))                  if (!(g_sock < 0))
237                  {                  {
238                          if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)                          if (connect(g_sock, res->ai_addr, res->ai_addrlen) == 0)
239                                  break;                                  break;
240                          close(sock);                          TCP_CLOSE(g_sock);
241                          sock = -1;                          g_sock = -1;
242                  }                  }
243                  res = res->ai_next;                  res = res->ai_next;
244          }          }
245          freeaddrinfo(ressave);          freeaddrinfo(ressave);
246    
247          if (sock == -1)          if (g_sock == -1)
248          {          {
249                  error("%s: unable to connect\n", server);                  error("%s: unable to connect\n", server);
250                  return False;                  return False;
# Line 191  tcp_connect(char *server) Line 265  tcp_connect(char *server)
265                  return False;                  return False;
266          }          }
267    
268          if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)          if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
269          {          {
270                  error("socket: %s\n", strerror(errno));                  error("socket: %s\n", TCP_STRERROR);
271                  return False;                  return False;
272          }          }
273    
274          servaddr.sin_family = AF_INET;          servaddr.sin_family = AF_INET;
275          servaddr.sin_port = htons(g_tcp_port_rdp);          servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
276    
277          if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)          if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
278          {          {
279                  error("connect: %s\n", strerror(errno));                  error("connect: %s\n", TCP_STRERROR);
280                  close(sock);                  TCP_CLOSE(g_sock);
281                  return False;                  return False;
282          }          }
283    
284  #endif /* IPv6 */  #endif /* IPv6 */
285    
286          setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));          option_value = 1;
287            option_len = sizeof(option_value);
288            setsockopt(g_sock, IPPROTO_TCP, TCP_NODELAY, (void *) &option_value, option_len);
289            /* receive buffer must be a least 16 K */
290            if (getsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value, &option_len) == 0)
291            {
292                    if (option_value < (1024 * 16))
293                    {
294                            option_value = 1024 * 16;
295                            option_len = sizeof(option_value);
296                            setsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value,
297                                       option_len);
298                    }
299            }
300    
301          in.size = 4096;          g_in.size = 4096;
302          in.data = (uint8 *) xmalloc(in.size);          g_in.data = (uint8 *) xmalloc(g_in.size);
303    
304          out.size = 4096;          for (i = 0; i < STREAM_COUNT; i++)
305          out.data = (uint8 *) xmalloc(out.size);          {
306                    g_out[i].size = 4096;
307                    g_out[i].data = (uint8 *) xmalloc(g_out[i].size);
308            }
309    
310          return True;          return True;
311  }  }
# Line 224  tcp_connect(char *server) Line 314  tcp_connect(char *server)
314  void  void
315  tcp_disconnect(void)  tcp_disconnect(void)
316  {  {
317          close(sock);          TCP_CLOSE(g_sock);
318  }  }
319    
320  char *  char *
# Line 233  tcp_get_address() Line 323  tcp_get_address()
323          static char ipaddr[32];          static char ipaddr[32];
324          struct sockaddr_in sockaddr;          struct sockaddr_in sockaddr;
325          socklen_t len = sizeof(sockaddr);          socklen_t len = sizeof(sockaddr);
326          if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)          if (getsockname(g_sock, (struct sockaddr *) &sockaddr, &len) == 0)
327          {          {
328                  unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;                  uint8 *ip = (uint8 *) & sockaddr.sin_addr;
329                  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]);
330          }          }
331          else          else
332                  strcpy(ipaddr, "127.0.0.1");                  strcpy(ipaddr, "127.0.0.1");
333          return ipaddr;          return ipaddr;
334  }  }
335    
336    /* reset the state of the tcp layer */
337    /* Support for Session Directory */
338    void
339    tcp_reset_state(void)
340    {
341            int i;
342    
343            g_sock = -1;            /* reset socket */
344    
345            /* Clear the incoming stream */
346            if (g_in.data != NULL)
347                    xfree(g_in.data);
348            g_in.p = NULL;
349            g_in.end = NULL;
350            g_in.data = NULL;
351            g_in.size = 0;
352            g_in.iso_hdr = NULL;
353            g_in.mcs_hdr = NULL;
354            g_in.sec_hdr = NULL;
355            g_in.rdp_hdr = NULL;
356            g_in.channel_hdr = NULL;
357    
358            /* Clear the outgoing stream(s) */
359            for (i = 0; i < STREAM_COUNT; i++)
360            {
361                    if (g_out[i].data != NULL)
362                            xfree(g_out[i].data);
363                    g_out[i].p = NULL;
364                    g_out[i].end = NULL;
365                    g_out[i].data = NULL;
366                    g_out[i].size = 0;
367                    g_out[i].iso_hdr = NULL;
368                    g_out[i].mcs_hdr = NULL;
369                    g_out[i].sec_hdr = NULL;
370                    g_out[i].rdp_hdr = NULL;
371                    g_out[i].channel_hdr = NULL;
372            }
373    }

Legend:
Removed from v.963  
changed lines
  Added in v.1475

  ViewVC Help
Powered by ViewVC 1.1.26