1 /* Serial interface for raw TCP connections on Un*x like systems.
2 
3    Copyright (C) 1992-2024 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 "serial.h"
21 #include "ser-base.h"
22 #include "ser-tcp.h"
23 #include "cli/cli-cmds.h"
24 #include "cli/cli-decode.h"
25 #include "cli/cli-setshow.h"
26 #include "gdbsupport/filestuff.h"
27 #include "gdbsupport/netstuff.h"
28 
29 #include <sys/types.h>
30 
31 #ifdef HAVE_SYS_FILIO_H
32 #include <sys/filio.h>
33 #endif
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37 
38 #include "gdbsupport/gdb_sys_time.h"
39 
40 #ifdef USE_WIN32API
41 #include <ws2tcpip.h>
42 #ifndef ETIMEDOUT
43 #define ETIMEDOUT WSAETIMEDOUT
44 #endif
45 /* Gnulib defines close too, but gnulib's replacement
46    doesn't call closesocket unless we import the
47    socketlib module.  */
48 #undef close
49 #define close(fd) closesocket (fd)
50 #define ioctl ioctlsocket
51 #else
52 #include <netinet/in.h>
53 #include <arpa/inet.h>
54 #include <netdb.h>
55 #include <sys/socket.h>
56 #include <netinet/tcp.h>
57 #endif
58 
59 #include <signal.h>
60 #include "gdbsupport/gdb_select.h"
61 #include <algorithm>
62 
63 #ifndef HAVE_SOCKLEN_T
64 typedef int socklen_t;
65 #endif
66 
67 /* For "set tcp" and "show tcp".  */
68 
69 static struct cmd_list_element *tcp_set_cmdlist;
70 static struct cmd_list_element *tcp_show_cmdlist;
71 
72 /* Whether to auto-retry refused connections.  */
73 
74 static bool tcp_auto_retry = true;
75 
76 /* Timeout period for connections, in seconds.  */
77 
78 static unsigned int tcp_retry_limit = 15;
79 
80 /* How many times per second to poll deprecated_ui_loop_hook.  */
81 
82 #define POLL_INTERVAL 5
83 
84 /* Helper function to wait a while.  If SOCK is not -1, wait on its
85    file descriptor.  Otherwise just wait on a timeout, updating
86    *POLLS.  Returns -1 on timeout or interrupt and set OUT_ERROR,
87    otherwise the value of select.  */
88 
89 static int
wait_for_connect(int sock,unsigned int * polls,ULONGEST * out_error)90 wait_for_connect (int sock, unsigned int *polls, ULONGEST *out_error)
91 {
92   struct timeval t;
93   int n;
94 
95   /* While we wait for the connect to complete,
96      poll the UI so it can update or the user can
97      interrupt.  */
98   if (deprecated_ui_loop_hook && deprecated_ui_loop_hook (0))
99     {
100       *out_error = EINTR;
101       return -1;
102     }
103 
104   /* Check for timeout.  */
105   if (*polls > tcp_retry_limit * POLL_INTERVAL)
106     {
107       *out_error = ETIMEDOUT;
108       return -1;
109     }
110 
111   /* Back off to polling once per second after the first POLL_INTERVAL
112      polls.  */
113   if (*polls < POLL_INTERVAL)
114     {
115       t.tv_sec = 0;
116       t.tv_usec = 1000000 / POLL_INTERVAL;
117     }
118   else
119     {
120       t.tv_sec = 1;
121       t.tv_usec = 0;
122     }
123 
124   if (sock >= 0)
125     {
126       fd_set rset, wset, eset;
127 
128       FD_ZERO (&rset);
129       FD_SET (sock, &rset);
130       wset = rset;
131       eset = rset;
132 
133       /* POSIX systems return connection success or failure by signalling
134            wset.  Windows systems return success in wset and failure in
135            eset.
136 
137            We must call select here, rather than gdb_select, because
138            the serial structure has not yet been initialized - the
139            MinGW select wrapper will not know that this FD refers
140            to a socket.  */
141       n = select (sock + 1, &rset, &wset, &eset, &t);
142     }
143   else
144     /* Use gdb_select here, since we have no file descriptors, and on
145        Windows, plain select doesn't work in that case.  */
146     n = interruptible_select (0, NULL, NULL, NULL, &t);
147 
148   /* If we didn't time out, only count it as one poll.  */
149   if (n > 0 || *polls < POLL_INTERVAL)
150     (*polls)++;
151   else
152     (*polls) += POLL_INTERVAL;
153 
154   return n;
155 }
156 
157 /* A helper to get the error number for either Windows or POSIX.  */
158 static ULONGEST
get_error()159 get_error ()
160 {
161 #ifdef USE_WIN32API
162   return WSAGetLastError ();
163 #else
164   return errno;
165 #endif
166 }
167 
168 /* Try to connect to the host represented by AINFO.  If the connection
169    succeeds, return its socket.  Otherwise, return -1 and set OUT_ERROR
170    accordingly.  POLLS is used when 'connect' returns EINPROGRESS, and
171    we need to invoke 'wait_for_connect' to obtain the status.  */
172 
173 static int
try_connect(const struct addrinfo * ainfo,unsigned int * polls,ULONGEST * out_error)174 try_connect (const struct addrinfo *ainfo, unsigned int *polls,
175                ULONGEST *out_error)
176 {
177   int sock = gdb_socket_cloexec (ainfo->ai_family, ainfo->ai_socktype,
178                                          ainfo->ai_protocol);
179 
180   if (sock < 0)
181     {
182       *out_error = get_error ();
183       return -1;
184     }
185 
186   /* Set socket nonblocking.  */
187 #ifdef USE_WIN32API
188   u_long ioarg = 1;
189 #else
190   int ioarg = 1;
191 #endif
192 
193   ioctl (sock, FIONBIO, &ioarg);
194 
195   /* Use Non-blocking connect.  connect() will return 0 if connected
196      already.  */
197   if (connect (sock, ainfo->ai_addr, ainfo->ai_addrlen) < 0)
198     {
199       ULONGEST err = get_error ();
200 
201       /* If we've got a "connection refused" error, just return
202            -1.  The caller will know what to do.  */
203       if (
204 #ifdef USE_WIN32API
205             err == WSAECONNREFUSED
206 #else
207             err == ECONNREFUSED
208 #endif
209             )
210           {
211             close (sock);
212             *out_error = err;
213             return -1;
214           }
215 
216       if (
217             /* Any other error (except EINPROGRESS) will be "swallowed"
218                here.  We return without specifying a return value, and
219                set errno if the caller wants to inspect what
220                happened.  */
221 #ifdef USE_WIN32API
222             /* Under Windows, calling "connect" with a non-blocking socket
223                results in WSAEWOULDBLOCK, not WSAEINPROGRESS.  */
224             err != WSAEWOULDBLOCK
225 #else
226             err != EINPROGRESS
227 #endif
228             )
229           {
230             close (sock);
231             *out_error = err;
232             return -1;
233           }
234 
235       /* Looks like we need to wait for the connect.  */
236       int n;
237 
238       do
239           n = wait_for_connect (sock, polls, out_error);
240       while (n == 0);
241 
242       if (n < 0)
243           {
244             /* A negative value here means that we either timed out or
245                got interrupted by the user.  Just return.  */
246             close (sock);
247             /* OUT_ERROR was set by wait_for_connect, above.  */
248             return -1;
249           }
250     }
251 
252   /* Got something.  Is it an error?  */
253   int err;
254   socklen_t len = sizeof (err);
255 
256   /* On Windows, the fourth parameter to getsockopt is a "char *";
257      on UNIX systems it is generally "void *".  The cast to "char *"
258      is OK everywhere, since in C++ any data pointer type can be
259      implicitly converted to "void *".  */
260   int ret = getsockopt (sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len);
261 
262   if (ret < 0)
263     {
264       *out_error = get_error ();
265       close (sock);
266       return -1;
267     }
268   else if (ret == 0 && err != 0)
269     {
270       *out_error = err;
271       close (sock);
272       return -1;
273     }
274 
275   /* The connection succeeded.  Return the socket.  */
276   return sock;
277 }
278 
279 /* Open a tcp socket.  */
280 
281 void
net_open(struct serial * scb,const char * name)282 net_open (struct serial *scb, const char *name)
283 {
284   struct addrinfo hint;
285   struct addrinfo *ainfo;
286 
287   memset (&hint, 0, sizeof (hint));
288   /* Assume no prefix will be passed, therefore we should use
289      AF_UNSPEC.  */
290   hint.ai_family = AF_UNSPEC;
291   hint.ai_socktype = SOCK_STREAM;
292   hint.ai_protocol = IPPROTO_TCP;
293 
294   parsed_connection_spec parsed = parse_connection_spec (name, &hint);
295 
296   if (parsed.port_str.empty ())
297     error (_("Missing port on hostname '%s'"), name);
298 
299   int r = getaddrinfo (parsed.host_str.c_str (),
300                            parsed.port_str.c_str (),
301                            &hint, &ainfo);
302 
303   if (r != 0)
304     error (_("%s: cannot resolve name: %s\n"), name, gai_strerror (r));
305 
306   scoped_free_addrinfo free_ainfo (ainfo);
307 
308   /* Flag to indicate whether we've got a connection refused.  It will
309      be true if any of the connections tried was refused.  */
310   bool got_connrefused;
311   /* If a connection succeeds, SUCCESS_AINFO will point to the
312      'struct addrinfo' that succeed.  */
313   struct addrinfo *success_ainfo = NULL;
314   unsigned int polls = 0;
315   ULONGEST last_error = 0;
316 
317   /* Assume the worst.  */
318   scb->fd = -1;
319 
320   do
321     {
322       got_connrefused = false;
323 
324       for (addrinfo *iter = ainfo; iter != NULL; iter = iter->ai_next)
325           {
326             /* Iterate over the list of possible addresses to connect
327                to.  For each, we'll try to connect and see if it
328                succeeds.  */
329             int sock = try_connect (iter, &polls, &last_error);
330 
331             if (sock >= 0)
332               {
333                 /* We've gotten a successful connection.  Save its
334                      'struct addrinfo', the socket, and break.  */
335                 success_ainfo = iter;
336                 scb->fd = sock;
337                 break;
338               }
339             else if (
340 #ifdef USE_WIN32API
341                        last_error == WSAECONNREFUSED
342 #else
343                        last_error == ECONNREFUSED
344 #endif
345                        )
346               got_connrefused = true;
347           }
348     }
349   /* Just retry if:
350 
351      - tcp_auto_retry is true, and
352      - We haven't gotten a connection yet, and
353      - Any of our connection attempts returned with ECONNREFUSED, and
354      - wait_for_connect signals that we can keep going.  */
355   while (tcp_auto_retry
356            && success_ainfo == NULL
357            && got_connrefused
358            && wait_for_connect (-1, &polls, &last_error) >= 0);
359 
360   if (success_ainfo == NULL)
361     {
362       net_close (scb);
363 #ifdef USE_WIN32API
364       throw_winerror_with_name (_("could not connect"), last_error);
365 #else
366       perror_with_name (_("could not connect"), last_error);
367 #endif
368     }
369 
370   /* Turn off nonblocking.  */
371 #ifdef USE_WIN32API
372   u_long ioarg = 0;
373 #else
374   int ioarg = 0;
375 #endif
376 
377   ioctl (scb->fd, FIONBIO, &ioarg);
378 
379   if (success_ainfo->ai_protocol == IPPROTO_TCP)
380     {
381       /* Disable Nagle algorithm.  Needed in some cases.  */
382       int tmp = 1;
383 
384       setsockopt (scb->fd, IPPROTO_TCP, TCP_NODELAY,
385                       (char *) &tmp, sizeof (tmp));
386     }
387 
388 #ifdef SIGPIPE
389   /* If we don't do this, then GDB simply exits
390      when the remote side dies.  */
391   signal (SIGPIPE, SIG_IGN);
392 #endif
393 }
394 
395 void
net_close(struct serial * scb)396 net_close (struct serial *scb)
397 {
398   if (scb->fd == -1)
399     return;
400 
401   close (scb->fd);
402   scb->fd = -1;
403 }
404 
405 int
net_read_prim(struct serial * scb,size_t count)406 net_read_prim (struct serial *scb, size_t count)
407 {
408   /* Need to cast to silence -Wpointer-sign on MinGW, as Winsock's
409      'recv' takes 'char *' as second argument, while 'scb->buf' is
410      'unsigned char *'.  */
411   int result = recv (scb->fd, (char *) scb->buf, count, 0);
412   if (result == -1 && errno != EINTR)
413     perror_with_name ("error while reading");
414   return result;
415 }
416 
417 int
net_write_prim(struct serial * scb,const void * buf,size_t count)418 net_write_prim (struct serial *scb, const void *buf, size_t count)
419 {
420   /* On Windows, the second parameter to send is a "const char *"; on
421      UNIX systems it is generally "const void *".  The cast to "const
422      char *" is OK everywhere, since in C++ any data pointer type can
423      be implicitly converted to "const void *".  */
424   int result = send (scb->fd, (const char *) buf, count, 0);
425   if (result == -1 && errno != EINTR)
426     perror_with_name ("error while writing");
427   return result;
428 }
429 
430 void
ser_tcp_send_break(struct serial * scb)431 ser_tcp_send_break (struct serial *scb)
432 {
433   /* Send telnet IAC and BREAK characters.  */
434   serial_write (scb, "\377\363", 2);
435 }
436 
437 #ifndef USE_WIN32API
438 
439 /* The TCP ops.  */
440 
441 static const struct serial_ops tcp_ops =
442 {
443   "tcp",
444   net_open,
445   net_close,
446   NULL,
447   ser_base_readchar,
448   ser_base_write,
449   ser_base_flush_output,
450   ser_base_flush_input,
451   ser_tcp_send_break,
452   ser_base_raw,
453   ser_base_get_tty_state,
454   ser_base_copy_tty_state,
455   ser_base_set_tty_state,
456   ser_base_print_tty_state,
457   ser_base_setbaudrate,
458   ser_base_setstopbits,
459   ser_base_setparity,
460   ser_base_drain_output,
461   ser_base_async,
462   net_read_prim,
463   net_write_prim
464 };
465 
466 #endif /* USE_WIN32API */
467 
468 void _initialize_ser_tcp ();
469 void
_initialize_ser_tcp()470 _initialize_ser_tcp ()
471 {
472 #ifdef USE_WIN32API
473   /* Do nothing; the TCP serial operations will be initialized in
474      ser-mingw.c.  */
475 #else
476   serial_add_interface (&tcp_ops);
477 #endif /* USE_WIN32API */
478 
479   add_setshow_prefix_cmd ("tcp", class_maintenance,
480                                 _("\
481 TCP protocol specific variables.\n\
482 Configure variables specific to remote TCP connections."),
483                                 _("\
484 TCP protocol specific variables.\n\
485 Configure variables specific to remote TCP connections."),
486                                 &tcp_set_cmdlist, &tcp_show_cmdlist,
487                                 &setlist, &showlist);
488 
489   add_setshow_boolean_cmd ("auto-retry", class_obscure,
490                                  &tcp_auto_retry, _("\
491 Set auto-retry on socket connect."), _("\
492 Show auto-retry on socket connect."),
493                                  NULL, NULL, NULL,
494                                  &tcp_set_cmdlist, &tcp_show_cmdlist);
495 
496   add_setshow_uinteger_cmd ("connect-timeout", class_obscure,
497                                   &tcp_retry_limit, _("\
498 Set timeout limit in seconds for socket connection."), _("\
499 Show timeout limit in seconds for socket connection."), _("\
500 If set to \"unlimited\", GDB will keep attempting to establish a\n\
501 connection forever, unless interrupted with Ctrl-c.\n\
502 The default is 15 seconds."),
503                                   NULL, NULL,
504                                   &tcp_set_cmdlist, &tcp_show_cmdlist);
505 }
506