xref: /dragonfly/contrib/gdb-7/gdb/ser-tcp.c (revision 1975d09e)
1 /* Serial interface for raw TCP connections on Un*x like systems.
2 
3    Copyright (C) 1992-2013 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 #include "serial.h"
22 #include "ser-base.h"
23 #include "ser-tcp.h"
24 #include "gdbcmd.h"
25 #include "cli/cli-decode.h"
26 #include "cli/cli-setshow.h"
27 
28 #include <sys/types.h>
29 
30 #ifdef HAVE_SYS_FILIO_H
31 #include <sys/filio.h>  /* For FIONBIO.  */
32 #endif
33 #ifdef HAVE_SYS_IOCTL_H
34 #include <sys/ioctl.h>  /* For FIONBIO.  */
35 #endif
36 
37 #include <sys/time.h>
38 
39 #ifdef USE_WIN32API
40 #include <winsock2.h>
41 #ifndef ETIMEDOUT
42 #define ETIMEDOUT WSAETIMEDOUT
43 #endif
44 #define close(fd) closesocket (fd)
45 #define ioctl ioctlsocket
46 #else
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49 #include <netdb.h>
50 #include <sys/socket.h>
51 #include <netinet/tcp.h>
52 #endif
53 
54 #include <signal.h>
55 #include "gdb_string.h"
56 #include "gdb_select.h"
57 
58 #ifndef HAVE_SOCKLEN_T
59 typedef int socklen_t;
60 #endif
61 
62 void _initialize_ser_tcp (void);
63 
64 /* For "set tcp" and "show tcp".  */
65 
66 static struct cmd_list_element *tcp_set_cmdlist;
67 static struct cmd_list_element *tcp_show_cmdlist;
68 
69 /* Whether to auto-retry refused connections.  */
70 
71 static int tcp_auto_retry = 1;
72 
73 /* Timeout period for connections, in seconds.  */
74 
75 static unsigned int tcp_retry_limit = 15;
76 
77 /* How many times per second to poll deprecated_ui_loop_hook.  */
78 
79 #define POLL_INTERVAL 5
80 
81 /* Helper function to wait a while.  If SCB is non-null, wait on its
82    file descriptor.  Otherwise just wait on a timeout, updating *POLLS.
83    Returns -1 on timeout or interrupt, otherwise the value of select.  */
84 
85 static int
86 wait_for_connect (struct serial *scb, int *polls)
87 {
88   struct timeval t;
89   int n;
90 
91   /* While we wait for the connect to complete,
92      poll the UI so it can update or the user can
93      interrupt.  */
94   if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
95     {
96       errno = EINTR;
97       return -1;
98     }
99 
100   /* Check for timeout.  */
101   if (*polls > tcp_retry_limit * POLL_INTERVAL)
102     {
103       errno = ETIMEDOUT;
104       return -1;
105     }
106 
107   /* Back off to polling once per second after the first POLL_INTERVAL
108      polls.  */
109   if (*polls < POLL_INTERVAL)
110     {
111       t.tv_sec = 0;
112       t.tv_usec = 1000000 / POLL_INTERVAL;
113     }
114   else
115     {
116       t.tv_sec = 1;
117       t.tv_usec = 0;
118     }
119 
120   if (scb)
121     {
122       fd_set rset, wset, eset;
123 
124       FD_ZERO (&rset);
125       FD_SET (scb->fd, &rset);
126       wset = rset;
127       eset = rset;
128 
129       /* POSIX systems return connection success or failure by signalling
130 	 wset.  Windows systems return success in wset and failure in
131 	 eset.
132 
133 	 We must call select here, rather than gdb_select, because
134 	 the serial structure has not yet been initialized - the
135 	 MinGW select wrapper will not know that this FD refers
136 	 to a socket.  */
137       n = select (scb->fd + 1, &rset, &wset, &eset, &t);
138     }
139   else
140     /* Use gdb_select here, since we have no file descriptors, and on
141        Windows, plain select doesn't work in that case.  */
142     n = gdb_select (0, NULL, NULL, NULL, &t);
143 
144   /* If we didn't time out, only count it as one poll.  */
145   if (n > 0 || *polls < POLL_INTERVAL)
146     (*polls)++;
147   else
148     (*polls) += POLL_INTERVAL;
149 
150   return n;
151 }
152 
153 /* Open a tcp socket.  */
154 
155 int
156 net_open (struct serial *scb, const char *name)
157 {
158   char *port_str, hostname[100];
159   int n, port, tmp;
160   int use_udp;
161   struct hostent *hostent;
162   struct sockaddr_in sockaddr;
163 #ifdef USE_WIN32API
164   u_long ioarg;
165 #else
166   int ioarg;
167 #endif
168   int polls = 0;
169 
170   use_udp = 0;
171   if (strncmp (name, "udp:", 4) == 0)
172     {
173       use_udp = 1;
174       name = name + 4;
175     }
176   else if (strncmp (name, "tcp:", 4) == 0)
177     name = name + 4;
178 
179   port_str = strchr (name, ':');
180 
181   if (!port_str)
182     error (_("net_open: No colon in host name!"));  /* Shouldn't ever
183 						       happen.  */
184 
185   tmp = min (port_str - name, (int) sizeof hostname - 1);
186   strncpy (hostname, name, tmp);	/* Don't want colon.  */
187   hostname[tmp] = '\000';	/* Tie off host name.  */
188   port = atoi (port_str + 1);
189 
190   /* Default hostname is localhost.  */
191   if (!hostname[0])
192     strcpy (hostname, "localhost");
193 
194   hostent = gethostbyname (hostname);
195   if (!hostent)
196     {
197       fprintf_unfiltered (gdb_stderr, "%s: unknown host\n", hostname);
198       errno = ENOENT;
199       return -1;
200     }
201 
202   sockaddr.sin_family = PF_INET;
203   sockaddr.sin_port = htons (port);
204   memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
205 	  sizeof (struct in_addr));
206 
207  retry:
208 
209   if (use_udp)
210     scb->fd = socket (PF_INET, SOCK_DGRAM, 0);
211   else
212     scb->fd = socket (PF_INET, SOCK_STREAM, 0);
213 
214   if (scb->fd == -1)
215     return -1;
216 
217   /* Set socket nonblocking.  */
218   ioarg = 1;
219   ioctl (scb->fd, FIONBIO, &ioarg);
220 
221   /* Use Non-blocking connect.  connect() will return 0 if connected
222      already.  */
223   n = connect (scb->fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
224 
225   if (n < 0)
226     {
227 #ifdef USE_WIN32API
228       int err = WSAGetLastError();
229 #else
230       int err = errno;
231 #endif
232 
233       /* Maybe we're waiting for the remote target to become ready to
234 	 accept connections.  */
235       if (tcp_auto_retry
236 #ifdef USE_WIN32API
237 	  && err == WSAECONNREFUSED
238 #else
239 	  && err == ECONNREFUSED
240 #endif
241 	  && wait_for_connect (NULL, &polls) >= 0)
242 	{
243 	  close (scb->fd);
244 	  goto retry;
245 	}
246 
247       if (
248 #ifdef USE_WIN32API
249 	  /* Under Windows, calling "connect" with a non-blocking socket
250 	     results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
251 	  err != WSAEWOULDBLOCK
252 #else
253 	  err != EINPROGRESS
254 #endif
255 	  )
256 	{
257 	  errno = err;
258 	  net_close (scb);
259 	  return -1;
260 	}
261 
262       /* Looks like we need to wait for the connect.  */
263       do
264 	{
265 	  n = wait_for_connect (scb, &polls);
266 	}
267       while (n == 0);
268       if (n < 0)
269 	{
270 	  net_close (scb);
271 	  return -1;
272 	}
273     }
274 
275   /* Got something.  Is it an error?  */
276   {
277     int res, err;
278     socklen_t len;
279 
280     len = sizeof (err);
281     /* On Windows, the fourth parameter to getsockopt is a "char *";
282        on UNIX systems it is generally "void *".  The cast to "void *"
283        is OK everywhere, since in C "void *" can be implicitly
284        converted to any pointer type.  */
285     res = getsockopt (scb->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len);
286     if (res < 0 || err)
287       {
288 	/* Maybe the target still isn't ready to accept the connection.  */
289 	if (tcp_auto_retry
290 #ifdef USE_WIN32API
291 	    && err == WSAECONNREFUSED
292 #else
293 	    && err == ECONNREFUSED
294 #endif
295 	    && wait_for_connect (NULL, &polls) >= 0)
296 	  {
297 	    close (scb->fd);
298 	    goto retry;
299 	  }
300 	if (err)
301 	  errno = err;
302 	net_close (scb);
303 	return -1;
304       }
305   }
306 
307   /* Turn off nonblocking.  */
308   ioarg = 0;
309   ioctl (scb->fd, FIONBIO, &ioarg);
310 
311   if (use_udp == 0)
312     {
313       /* Disable Nagle algorithm.  Needed in some cases.  */
314       tmp = 1;
315       setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
316 		  (char *)&tmp, sizeof (tmp));
317     }
318 
319 #ifdef SIGPIPE
320   /* If we don't do this, then GDB simply exits
321      when the remote side dies.  */
322   signal (SIGPIPE, SIG_IGN);
323 #endif
324 
325   return 0;
326 }
327 
328 void
329 net_close (struct serial *scb)
330 {
331   if (scb->fd == -1)
332     return;
333 
334   close (scb->fd);
335   scb->fd = -1;
336 }
337 
338 int
339 net_read_prim (struct serial *scb, size_t count)
340 {
341   return recv (scb->fd, scb->buf, count, 0);
342 }
343 
344 int
345 net_write_prim (struct serial *scb, const void *buf, size_t count)
346 {
347   return send (scb->fd, buf, count, 0);
348 }
349 
350 int
351 ser_tcp_send_break (struct serial *scb)
352 {
353   /* Send telnet IAC and BREAK characters.  */
354   return (serial_write (scb, "\377\363", 2));
355 }
356 
357 /* Support for "set tcp" and "show tcp" commands.  */
358 
359 static void
360 set_tcp_cmd (char *args, int from_tty)
361 {
362   help_list (tcp_set_cmdlist, "set tcp ", -1, gdb_stdout);
363 }
364 
365 static void
366 show_tcp_cmd (char *args, int from_tty)
367 {
368   help_list (tcp_show_cmdlist, "show tcp ", -1, gdb_stdout);
369 }
370 
371 
372 void
373 _initialize_ser_tcp (void)
374 {
375 #ifdef USE_WIN32API
376   /* Do nothing; the TCP serial operations will be initialized in
377      ser-mingw.c.  */
378 #else
379   struct serial_ops *ops;
380 
381   ops = XMALLOC (struct serial_ops);
382   memset (ops, 0, sizeof (struct serial_ops));
383   ops->name = "tcp";
384   ops->next = 0;
385   ops->open = net_open;
386   ops->close = net_close;
387   ops->readchar = ser_base_readchar;
388   ops->write = ser_base_write;
389   ops->flush_output = ser_base_flush_output;
390   ops->flush_input = ser_base_flush_input;
391   ops->send_break = ser_tcp_send_break;
392   ops->go_raw = ser_base_raw;
393   ops->get_tty_state = ser_base_get_tty_state;
394   ops->copy_tty_state = ser_base_copy_tty_state;
395   ops->set_tty_state = ser_base_set_tty_state;
396   ops->print_tty_state = ser_base_print_tty_state;
397   ops->noflush_set_tty_state = ser_base_noflush_set_tty_state;
398   ops->setbaudrate = ser_base_setbaudrate;
399   ops->setstopbits = ser_base_setstopbits;
400   ops->drain_output = ser_base_drain_output;
401   ops->async = ser_base_async;
402   ops->read_prim = net_read_prim;
403   ops->write_prim = net_write_prim;
404   serial_add_interface (ops);
405 #endif /* USE_WIN32API */
406 
407   add_prefix_cmd ("tcp", class_maintenance, set_tcp_cmd, _("\
408 TCP protocol specific variables\n\
409 Configure variables specific to remote TCP connections"),
410 		  &tcp_set_cmdlist, "set tcp ",
411 		  0 /* allow-unknown */, &setlist);
412   add_prefix_cmd ("tcp", class_maintenance, show_tcp_cmd, _("\
413 TCP protocol specific variables\n\
414 Configure variables specific to remote TCP connections"),
415 		  &tcp_show_cmdlist, "show tcp ",
416 		  0 /* allow-unknown */, &showlist);
417 
418   add_setshow_boolean_cmd ("auto-retry", class_obscure,
419 			   &tcp_auto_retry, _("\
420 Set auto-retry on socket connect"), _("\
421 Show auto-retry on socket connect"),
422 			   NULL, NULL, NULL,
423 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
424 
425   add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
426 			    &tcp_retry_limit, _("\
427 Set timeout limit for socket connection"), _("\
428 Show timeout limit for socket connection"),
429 			   NULL, NULL, NULL,
430 			   &tcp_set_cmdlist, &tcp_show_cmdlist);
431 }
432