Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentcp.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 = ∈ 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
1.7.6.1
|