ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcp.c
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 8 -*-
00002    rdesktop: A Remote Desktop Protocol client.
00003    Protocol services - TCP layer
00004    Copyright (C) Matthew Chapman 1999-2005
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 along
00017    with this program; if not, write to the Free Software Foundation, Inc.,
00018    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019 */
00020 
00021 
00022 #include <precomp.h>
00023 
00024 #ifdef _WIN32
00025 #define socklen_t int
00026 #define TCP_CLOSE(_sck) closesocket(_sck)
00027 #define TCP_STRERROR "tcp error"
00028 #define TCP_SLEEP(_n) Sleep(_n)
00029 #define TCP_BLOCKS (WSAGetLastError() == WSAEWOULDBLOCK)
00030 #else /* _WIN32 */
00031 #define TCP_CLOSE(_sck) close(_sck)
00032 #define TCP_STRERROR strerror(errno)
00033 #define TCP_SLEEP(_n) sleep(_n)
00034 #define TCP_BLOCKS (errno == EWOULDBLOCK)
00035 #endif /* _WIN32 */
00036 
00037 #ifndef INADDR_NONE
00038 #define INADDR_NONE ((unsigned long) -1)
00039 #endif
00040 
00041 static int sock;
00042 static struct stream in;
00043 static struct stream out;
00044 int g_tcp_port_rdp = TCP_PORT_RDP;
00045 
00046 /* Initialise TCP transport data packet */
00047 STREAM
00048 tcp_init(uint32 maxlen)
00049 {
00050     if (maxlen > out.size)
00051     {
00052         out.data = (uint8 *) xrealloc(out.data, maxlen);
00053         out.size = maxlen;
00054     }
00055 
00056     out.p = out.data;
00057     out.end = out.data + out.size;
00058     return &out;
00059 }
00060 
00061 /* Send TCP transport data packet */
00062 void
00063 tcp_send(STREAM s)
00064 {
00065     int length = s->end - s->data;
00066     int sent, total = 0;
00067 
00068     while (total < length)
00069     {
00070         sent = send(sock, (char *)s->data + total, length - total, 0);
00071         if (sent <= 0)
00072         {
00073             if (sent == -1 && TCP_BLOCKS)
00074             {
00075                 TCP_SLEEP(0);
00076                 sent = 0;
00077             }
00078             else
00079             {
00080                 error("send: %s\n", TCP_STRERROR);
00081                 return;
00082             }
00083         }
00084         total += sent;
00085     }
00086 }
00087 
00088 /* Receive a message on the TCP layer */
00089 STREAM
00090 tcp_recv(STREAM s, uint32 length)
00091 {
00092     unsigned int new_length, end_offset, p_offset;
00093     int rcvd = 0;
00094 
00095     if (s == NULL)
00096     {
00097         /* read into "new" stream */
00098         if (length > in.size)
00099         {
00100             in.data = (uint8 *) xrealloc(in.data, length);
00101             in.size = length;
00102         }
00103         in.end = in.p = in.data;
00104         s = &in;
00105     }
00106     else
00107     {
00108         /* append to existing stream */
00109         new_length = (s->end - s->data) + length;
00110         if (new_length > s->size)
00111         {
00112             p_offset = s->p - s->data;
00113             end_offset = s->end - s->data;
00114             s->data = (uint8 *) xrealloc(s->data, new_length);
00115             s->size = new_length;
00116             s->p = s->data + p_offset;
00117             s->end = s->data + end_offset;
00118         }
00119     }
00120 
00121     while (length > 0)
00122     {
00123         if (!ui_select(sock))
00124             /* User quit */
00125             return NULL;
00126 
00127         rcvd = recv(sock, (char *)s->end, length, 0);
00128         if (rcvd < 0)
00129         {
00130             if (rcvd == -1 && TCP_BLOCKS)
00131             {
00132                 TCP_SLEEP(0);
00133                 rcvd = 0;
00134             }
00135             else
00136             {
00137                 error("recv: %s\n", TCP_STRERROR);
00138                 return NULL;
00139             }
00140         }
00141         else if (rcvd == 0)
00142         {
00143             error("Connection closed\n");
00144             return NULL;
00145         }
00146 
00147         s->end += rcvd;
00148         length -= rcvd;
00149     }
00150 
00151     return s;
00152 }
00153 
00154 /* Establish a connection on the TCP layer */
00155 BOOL
00156 tcp_connect(char *server)
00157 {
00158     int true_value = 1;
00159 
00160 #ifdef IPv6
00161 
00162     int n;
00163     struct addrinfo hints, *res, *ressave;
00164     char tcp_port_rdp_s[10];
00165 
00166     snprintf(tcp_port_rdp_s, 10, "%d", g_tcp_port_rdp);
00167 
00168     memset(&hints, 0, sizeof(struct addrinfo));
00169     hints.ai_family = AF_UNSPEC;
00170     hints.ai_socktype = SOCK_STREAM;
00171 
00172     if ((n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res)))
00173     {
00174         error("getaddrinfo: %s\n", gai_strerror(n));
00175         return False;
00176     }
00177 
00178     ressave = res;
00179     sock = -1;
00180     while (res)
00181     {
00182         sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
00183         if (!(sock < 0))
00184         {
00185             if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
00186                 break;
00187             TCP_CLOSE(sock);
00188             sock = -1;
00189         }
00190         res = res->ai_next;
00191     }
00192     freeaddrinfo(ressave);
00193 
00194     if (sock == -1)
00195     {
00196         error("%s: unable to connect\n", server);
00197         return False;
00198     }
00199 
00200 #else /* no IPv6 support */
00201 
00202     struct hostent *nslookup;
00203     struct sockaddr_in servaddr;
00204 
00205     if ((nslookup = gethostbyname(server)) != NULL)
00206     {
00207         memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
00208     }
00209     else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
00210     {
00211         error("%s: unable to resolve host\n", server);
00212         return False;
00213     }
00214 
00215     if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
00216     {
00217         error("socket: %s\n", TCP_STRERROR);
00218         return False;
00219     }
00220 
00221     servaddr.sin_family = AF_INET;
00222     servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
00223 
00224     if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
00225     {
00226         error("connect: %s\n", TCP_STRERROR);
00227         TCP_CLOSE(sock);
00228         return False;
00229     }
00230 
00231 #endif /* IPv6 */
00232 
00233     setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
00234 
00235     in.size = 4096;
00236     in.data = (uint8 *) xmalloc(in.size);
00237 
00238     out.size = 4096;
00239     out.data = (uint8 *) xmalloc(out.size);
00240 
00241     return True;
00242 }
00243 
00244 /* Disconnect on the TCP layer */
00245 void
00246 tcp_disconnect(void)
00247 {
00248     TCP_CLOSE(sock);
00249 }
00250 
00251 char *
00252 tcp_get_address()
00253 {
00254     static char ipaddr[32];
00255     struct sockaddr_in sockaddr;
00256     socklen_t len = sizeof(sockaddr);
00257     if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)
00258     {
00259         unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;
00260         sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
00261     }
00262     else
00263         strcpy(ipaddr, "127.0.0.1");
00264     return ipaddr;
00265 }
00266 
00267 /* reset the state of the tcp layer */
00268 /* Support for Session Directory */
00269 void
00270 tcp_reset_state(void)
00271 {
00272     sock = -1;      /* reset socket */
00273 
00274     /* Clear the incoming stream */
00275     if (in.data != NULL)
00276         xfree(in.data);
00277     in.p = NULL;
00278     in.end = NULL;
00279     in.data = NULL;
00280     in.size = 0;
00281     in.iso_hdr = NULL;
00282     in.mcs_hdr = NULL;
00283     in.sec_hdr = NULL;
00284     in.rdp_hdr = NULL;
00285     in.channel_hdr = NULL;
00286 
00287     /* Clear the outgoing stream */
00288     if (out.data != NULL)
00289         xfree(out.data);
00290     out.p = NULL;
00291     out.end = NULL;
00292     out.data = NULL;
00293     out.size = 0;
00294     out.iso_hdr = NULL;
00295     out.mcs_hdr = NULL;
00296     out.sec_hdr = NULL;
00297     out.rdp_hdr = NULL;
00298     out.channel_hdr = NULL;
00299 }

Generated on Sun May 27 2012 04:17:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.