Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

tcp.cpp

Go to the documentation of this file.
00001 /*
00002    rdesktop: A Remote Desktop Protocol client.
00003    Protocol services - TCP layer
00004    Copyright (C) Matthew Chapman 1999-2002
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include <unistd.h>             /* select read write close */
00022 #include <sys/socket.h>         /* socket connect setsockopt */
00023 #include <sys/time.h>           /* timeval */
00024 #include <netdb.h>              /* gethostbyname */
00025 #include <netinet/in.h>         /* sockaddr_in */
00026 #include <netinet/tcp.h>        /* TCP_NODELAY */
00027 #include <arpa/inet.h>          /* inet_addr */
00028 #include <fcntl.h>
00029 #include <errno.h>              /* errno */
00030 #include "rdesktop.h"
00031 
00032 #ifndef INADDR_NONE
00033 #define INADDR_NONE ((unsigned long) -1)
00034 #endif
00035 
00036 static int sock;
00037 static struct stream in;
00038 static struct stream out;
00039 extern int tcp_port_rdp;
00040 
00041 /* Initialise TCP transport data packet */
00042 STREAM
00043 tcp_init(unsigned int maxlen)
00044 {
00045         if (maxlen > out.size)
00046         {
00047                 out.data = (unsigned char*)xrealloc(out.data, maxlen);
00048                 out.size = maxlen;
00049         }
00050 
00051         out.p = out.data;
00052         out.end = out.data + out.size;
00053         return &out;
00054 }
00055 
00056 /* Send TCP transport data packet */
00057 void
00058 tcp_send(STREAM s)
00059 {
00060         int length = s->end - s->data;
00061         int sent, total = 0;
00062 
00063         while (total < length)
00064         {
00065                 sent = send(sock, s->data + total, length - total, 0);
00066                 if (sent == -1 && errno == EWOULDBLOCK)
00067                 {
00068                         usleep(1000);
00069                 }
00070                 else if (sent <= 0)
00071                 {
00072                         error("send: %s\n", strerror(errno));
00073                         return;
00074                 }
00075                 else
00076                         total += sent;
00077         }
00078 }
00079 
00080 /* Receive a message on the TCP layer */
00081 STREAM
00082 tcp_recv(unsigned int length)
00083 {
00084         int rcvd = 0;
00085 
00086         if (length > in.size)
00087         {
00088                 in.data = (unsigned char*)xrealloc(in.data, length);
00089                 in.size = length;
00090         }
00091 
00092         in.end = in.p = in.data;
00093 
00094         while (length > 0)
00095         {
00096                 if (!ui_select(sock))
00097                         /* User quit */
00098                         return NULL;
00099 
00100                 rcvd = recv(sock, in.end, length, 0);
00101                 if (rcvd == -1 && errno == EWOULDBLOCK)
00102                 {
00103                         usleep(1000);
00104                 }
00105                 else if (rcvd == -1)
00106                 {
00107                         error("recv: %s\n", strerror(errno));
00108                         return NULL;
00109                 }
00110                 else if (rcvd == 0)
00111                         return NULL;
00112                 else
00113                 {
00114                         in.end += rcvd;
00115                         length -= rcvd;
00116                 }
00117         }
00118 
00119         return &in;
00120 }
00121 
00122 /* Establish a connection on the TCP layer */
00123 BOOL
00124 tcp_connect(char *server)
00125 {
00126         struct hostent *nslookup;
00127         struct sockaddr_in servaddr;
00128         int l_true = 1;
00129 
00130         if ((nslookup = gethostbyname(server)) != NULL)
00131         {
00132                 memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
00133         }
00134         else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
00135         {
00136                 error("%s: unable to resolve host\n", server);
00137                 return False;
00138         }
00139 
00140         if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
00141         {
00142                 error("socket: %s\n", strerror(errno));
00143                 return False;
00144         }
00145 
00146         servaddr.sin_family = AF_INET;
00147         servaddr.sin_port = htons(tcp_port_rdp);
00148 
00149         if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
00150         {
00151                 error("connect: %s\n", strerror(errno));
00152                 close(sock);
00153                 return False;
00154         }
00155 
00156         /* set non blocking */
00157         {
00158                 int op;
00159                 op = fcntl(sock, F_GETFL);
00160                 op |= O_NONBLOCK;
00161                 fcntl(sock, F_SETFL, op);
00162         }
00163 
00164 //      fcntl(sock, O_NONBLOCK);
00165         setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &l_true, sizeof(l_true));
00166 
00167         in.size = 4096;
00168         in.data = (unsigned char*)xmalloc(in.size);
00169 
00170         out.size = 4096;
00171         out.data = (unsigned char*)xmalloc(out.size);
00172 
00173         return True;
00174 }
00175 
00176 /* Disconnect on the TCP layer */
00177 void
00178 tcp_disconnect(void)
00179 {
00180         close(sock);
00181 }

Generated on Sat Nov 5 16:17:42 2005 for OPIE by  doxygen 1.4.2