GDB (API)
|
00001 /* Serial interface for raw TCP connections on Un*x like systems. 00002 00003 Copyright (C) 1992-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "serial.h" 00022 #include "ser-base.h" 00023 #include "ser-tcp.h" 00024 #include "gdbcmd.h" 00025 #include "cli/cli-decode.h" 00026 #include "cli/cli-setshow.h" 00027 #include "filestuff.h" 00028 00029 #include <sys/types.h> 00030 00031 #ifdef HAVE_SYS_FILIO_H 00032 #include <sys/filio.h> /* For FIONBIO. */ 00033 #endif 00034 #ifdef HAVE_SYS_IOCTL_H 00035 #include <sys/ioctl.h> /* For FIONBIO. */ 00036 #endif 00037 00038 #include <sys/time.h> 00039 00040 #ifdef USE_WIN32API 00041 #include <winsock2.h> 00042 #ifndef ETIMEDOUT 00043 #define ETIMEDOUT WSAETIMEDOUT 00044 #endif 00045 #define close(fd) closesocket (fd) 00046 #define ioctl ioctlsocket 00047 #else 00048 #include <netinet/in.h> 00049 #include <arpa/inet.h> 00050 #include <netdb.h> 00051 #include <sys/socket.h> 00052 #include <netinet/tcp.h> 00053 #endif 00054 00055 #include <signal.h> 00056 #include "gdb_string.h" 00057 #include "gdb_select.h" 00058 00059 #ifndef HAVE_SOCKLEN_T 00060 typedef int socklen_t; 00061 #endif 00062 00063 void _initialize_ser_tcp (void); 00064 00065 /* For "set tcp" and "show tcp". */ 00066 00067 static struct cmd_list_element *tcp_set_cmdlist; 00068 static struct cmd_list_element *tcp_show_cmdlist; 00069 00070 /* Whether to auto-retry refused connections. */ 00071 00072 static int tcp_auto_retry = 1; 00073 00074 /* Timeout period for connections, in seconds. */ 00075 00076 static unsigned int tcp_retry_limit = 15; 00077 00078 /* How many times per second to poll deprecated_ui_loop_hook. */ 00079 00080 #define POLL_INTERVAL 5 00081 00082 /* Helper function to wait a while. If SCB is non-null, wait on its 00083 file descriptor. Otherwise just wait on a timeout, updating *POLLS. 00084 Returns -1 on timeout or interrupt, otherwise the value of select. */ 00085 00086 static int 00087 wait_for_connect (struct serial *scb, unsigned int *polls) 00088 { 00089 struct timeval t; 00090 int n; 00091 00092 /* While we wait for the connect to complete, 00093 poll the UI so it can update or the user can 00094 interrupt. */ 00095 if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0)) 00096 { 00097 errno = EINTR; 00098 return -1; 00099 } 00100 00101 /* Check for timeout. */ 00102 if (*polls > tcp_retry_limit * POLL_INTERVAL) 00103 { 00104 errno = ETIMEDOUT; 00105 return -1; 00106 } 00107 00108 /* Back off to polling once per second after the first POLL_INTERVAL 00109 polls. */ 00110 if (*polls < POLL_INTERVAL) 00111 { 00112 t.tv_sec = 0; 00113 t.tv_usec = 1000000 / POLL_INTERVAL; 00114 } 00115 else 00116 { 00117 t.tv_sec = 1; 00118 t.tv_usec = 0; 00119 } 00120 00121 if (scb) 00122 { 00123 fd_set rset, wset, eset; 00124 00125 FD_ZERO (&rset); 00126 FD_SET (scb->fd, &rset); 00127 wset = rset; 00128 eset = rset; 00129 00130 /* POSIX systems return connection success or failure by signalling 00131 wset. Windows systems return success in wset and failure in 00132 eset. 00133 00134 We must call select here, rather than gdb_select, because 00135 the serial structure has not yet been initialized - the 00136 MinGW select wrapper will not know that this FD refers 00137 to a socket. */ 00138 n = select (scb->fd + 1, &rset, &wset, &eset, &t); 00139 } 00140 else 00141 /* Use gdb_select here, since we have no file descriptors, and on 00142 Windows, plain select doesn't work in that case. */ 00143 n = gdb_select (0, NULL, NULL, NULL, &t); 00144 00145 /* If we didn't time out, only count it as one poll. */ 00146 if (n > 0 || *polls < POLL_INTERVAL) 00147 (*polls)++; 00148 else 00149 (*polls) += POLL_INTERVAL; 00150 00151 return n; 00152 } 00153 00154 /* Open a tcp socket. */ 00155 00156 int 00157 net_open (struct serial *scb, const char *name) 00158 { 00159 char *port_str, hostname[100]; 00160 int n, port, tmp; 00161 int use_udp; 00162 struct hostent *hostent; 00163 struct sockaddr_in sockaddr; 00164 #ifdef USE_WIN32API 00165 u_long ioarg; 00166 #else 00167 int ioarg; 00168 #endif 00169 unsigned int polls = 0; 00170 00171 use_udp = 0; 00172 if (strncmp (name, "udp:", 4) == 0) 00173 { 00174 use_udp = 1; 00175 name = name + 4; 00176 } 00177 else if (strncmp (name, "tcp:", 4) == 0) 00178 name = name + 4; 00179 00180 port_str = strchr (name, ':'); 00181 00182 if (!port_str) 00183 error (_("net_open: No colon in host name!")); /* Shouldn't ever 00184 happen. */ 00185 00186 tmp = min (port_str - name, (int) sizeof hostname - 1); 00187 strncpy (hostname, name, tmp); /* Don't want colon. */ 00188 hostname[tmp] = '\000'; /* Tie off host name. */ 00189 port = atoi (port_str + 1); 00190 00191 /* Default hostname is localhost. */ 00192 if (!hostname[0]) 00193 strcpy (hostname, "localhost"); 00194 00195 hostent = gethostbyname (hostname); 00196 if (!hostent) 00197 { 00198 fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname); 00199 errno = ENOENT; 00200 return -1; 00201 } 00202 00203 sockaddr.sin_family = PF_INET; 00204 sockaddr.sin_port = htons (port); 00205 memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr, 00206 sizeof (struct in_addr)); 00207 00208 retry: 00209 00210 if (use_udp) 00211 scb->fd = gdb_socket_cloexec (PF_INET, SOCK_DGRAM, 0); 00212 else 00213 scb->fd = gdb_socket_cloexec (PF_INET, SOCK_STREAM, 0); 00214 00215 if (scb->fd == -1) 00216 return -1; 00217 00218 /* Set socket nonblocking. */ 00219 ioarg = 1; 00220 ioctl (scb->fd, FIONBIO, &ioarg); 00221 00222 /* Use Non-blocking connect. connect() will return 0 if connected 00223 already. */ 00224 n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)); 00225 00226 if (n < 0) 00227 { 00228 #ifdef USE_WIN32API 00229 int err = WSAGetLastError(); 00230 #else 00231 int err = errno; 00232 #endif 00233 00234 /* Maybe we're waiting for the remote target to become ready to 00235 accept connections. */ 00236 if (tcp_auto_retry 00237 #ifdef USE_WIN32API 00238 && err == WSAECONNREFUSED 00239 #else 00240 && err == ECONNREFUSED 00241 #endif 00242 && wait_for_connect (NULL, &polls) >= 0) 00243 { 00244 close (scb->fd); 00245 goto retry; 00246 } 00247 00248 if ( 00249 #ifdef USE_WIN32API 00250 /* Under Windows, calling "connect" with a non-blocking socket 00251 results in WSAEWOULDBLOCK, not WSAEINPROGRESS. */ 00252 err != WSAEWOULDBLOCK 00253 #else 00254 err != EINPROGRESS 00255 #endif 00256 ) 00257 { 00258 errno = err; 00259 net_close (scb); 00260 return -1; 00261 } 00262 00263 /* Looks like we need to wait for the connect. */ 00264 do 00265 { 00266 n = wait_for_connect (scb, &polls); 00267 } 00268 while (n == 0); 00269 if (n < 0) 00270 { 00271 net_close (scb); 00272 return -1; 00273 } 00274 } 00275 00276 /* Got something. Is it an error? */ 00277 { 00278 int res, err; 00279 socklen_t len; 00280 00281 len = sizeof (err); 00282 /* On Windows, the fourth parameter to getsockopt is a "char *"; 00283 on UNIX systems it is generally "void *". The cast to "void *" 00284 is OK everywhere, since in C "void *" can be implicitly 00285 converted to any pointer type. */ 00286 res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len); 00287 if (res < 0 || err) 00288 { 00289 /* Maybe the target still isn't ready to accept the connection. */ 00290 if (tcp_auto_retry 00291 #ifdef USE_WIN32API 00292 && err == WSAECONNREFUSED 00293 #else 00294 && err == ECONNREFUSED 00295 #endif 00296 && wait_for_connect (NULL, &polls) >= 0) 00297 { 00298 close (scb->fd); 00299 goto retry; 00300 } 00301 if (err) 00302 errno = err; 00303 net_close (scb); 00304 return -1; 00305 } 00306 } 00307 00308 /* Turn off nonblocking. */ 00309 ioarg = 0; 00310 ioctl (scb->fd, FIONBIO, &ioarg); 00311 00312 if (use_udp == 0) 00313 { 00314 /* Disable Nagle algorithm. Needed in some cases. */ 00315 tmp = 1; 00316 setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY, 00317 (char *)&tmp, sizeof (tmp)); 00318 } 00319 00320 #ifdef SIGPIPE 00321 /* If we don't do this, then GDB simply exits 00322 when the remote side dies. */ 00323 signal (SIGPIPE, SIG_IGN); 00324 #endif 00325 00326 return 0; 00327 } 00328 00329 void 00330 net_close (struct serial *scb) 00331 { 00332 if (scb->fd == -1) 00333 return; 00334 00335 close (scb->fd); 00336 scb->fd = -1; 00337 } 00338 00339 int 00340 net_read_prim (struct serial *scb, size_t count) 00341 { 00342 /* Need to cast to silence -Wpointer-sign on MinGW, as Winsock's 00343 'recv' takes 'char *' as second argument, while 'scb->buf' is 00344 'unsigned char *'. */ 00345 return recv (scb->fd, (void *) scb->buf, count, 0); 00346 } 00347 00348 int 00349 net_write_prim (struct serial *scb, const void *buf, size_t count) 00350 { 00351 return send (scb->fd, buf, count, 0); 00352 } 00353 00354 int 00355 ser_tcp_send_break (struct serial *scb) 00356 { 00357 /* Send telnet IAC and BREAK characters. */ 00358 return (serial_write (scb, "\377\363", 2)); 00359 } 00360 00361 /* Support for "set tcp" and "show tcp" commands. */ 00362 00363 static void 00364 set_tcp_cmd (char *args, int from_tty) 00365 { 00366 help_list (tcp_set_cmdlist, "set tcp ", -1, gdb_stdout); 00367 } 00368 00369 static void 00370 show_tcp_cmd (char *args, int from_tty) 00371 { 00372 help_list (tcp_show_cmdlist, "show tcp ", -1, gdb_stdout); 00373 } 00374 00375 00376 void 00377 _initialize_ser_tcp (void) 00378 { 00379 #ifdef USE_WIN32API 00380 /* Do nothing; the TCP serial operations will be initialized in 00381 ser-mingw.c. */ 00382 #else 00383 struct serial_ops *ops; 00384 00385 ops = XMALLOC (struct serial_ops); 00386 memset (ops, 0, sizeof (struct serial_ops)); 00387 ops->name = "tcp"; 00388 ops->next = 0; 00389 ops->open = net_open; 00390 ops->close = net_close; 00391 ops->readchar = ser_base_readchar; 00392 ops->write = ser_base_write; 00393 ops->flush_output = ser_base_flush_output; 00394 ops->flush_input = ser_base_flush_input; 00395 ops->send_break = ser_tcp_send_break; 00396 ops->go_raw = ser_base_raw; 00397 ops->get_tty_state = ser_base_get_tty_state; 00398 ops->copy_tty_state = ser_base_copy_tty_state; 00399 ops->set_tty_state = ser_base_set_tty_state; 00400 ops->print_tty_state = ser_base_print_tty_state; 00401 ops->noflush_set_tty_state = ser_base_noflush_set_tty_state; 00402 ops->setbaudrate = ser_base_setbaudrate; 00403 ops->setstopbits = ser_base_setstopbits; 00404 ops->drain_output = ser_base_drain_output; 00405 ops->async = ser_base_async; 00406 ops->read_prim = net_read_prim; 00407 ops->write_prim = net_write_prim; 00408 serial_add_interface (ops); 00409 #endif /* USE_WIN32API */ 00410 00411 add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\ 00412 TCP protocol specific variables\n\ 00413 Configure variables specific to remote TCP connections"), 00414 &tcp_set_cmdlist, "set tcp ", 00415 0 /* allow-unknown */, &setlist); 00416 add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\ 00417 TCP protocol specific variables\n\ 00418 Configure variables specific to remote TCP connections"), 00419 &tcp_show_cmdlist, "show tcp ", 00420 0 /* allow-unknown */, &showlist); 00421 00422 add_setshow_boolean_cmd ("auto-retry", class_obscure, 00423 &tcp_auto_retry, _("\ 00424 Set auto-retry on socket connect"), _("\ 00425 Show auto-retry on socket connect"), 00426 NULL, NULL, NULL, 00427 &tcp_set_cmdlist, &tcp_show_cmdlist); 00428 00429 add_setshow_uinteger_cmd ("connect-timeout", class_obscure, 00430 &tcp_retry_limit, _("\ 00431 Set timeout limit in seconds for socket connection"), _("\ 00432 Show timeout limit in seconds for socket connection"), _("\ 00433 If set to \"unlimited\", GDB will keep attempting to establish a\n\ 00434 connection forever, unless interrupted with Ctrl-c.\n\ 00435 The default is 15 seconds."), 00436 NULL, NULL, 00437 &tcp_set_cmdlist, &tcp_show_cmdlist); 00438 }