]>
Commit | Line | Data |
---|---|---|
5580185e | 1 | /* |
a4fafd85 | 2 | * $Source$ |
3 | * $Header$ | |
5580185e | 4 | */ |
5 | ||
6 | #ifndef lint | |
7 | static char *rcsid_gdb_conn_c = "$Header$"; | |
d9f43d51 | 8 | #endif |
5580185e | 9 | |
a4fafd85 | 10 | /************************************************************************ |
11 | * | |
12 | * gdb_conn.c | |
13 | * | |
14 | * GDB - Connection Management Services | |
15 | * | |
16 | * Author: Noah Mendelsohn | |
17 | * Copyright: 1986 MIT Project Athena | |
18 | * For copying and distribution information, please see | |
19 | * the file <mit-copyright.h>. | |
20 | * | |
21 | * Routines used in the creation and maintenance of CONNECTIONS. | |
22 | * Note: these are closely related to the services provided | |
23 | * by gdb_trans.c and gdb_trans2.c. | |
24 | * | |
25 | * | |
26 | ************************************************************************/ | |
5580185e | 27 | |
0a5ff702 | 28 | #include <mit-copyright.h> |
5580185e | 29 | #include <stdio.h> |
d9f43d51 | 30 | #include <stdlib.h> |
8fd777cf | 31 | #include <string.h> |
5580185e | 32 | #include "gdb.h" |
33 | #include <sys/types.h> | |
34 | #include <sys/uio.h> | |
35 | #include <sys/socket.h> | |
36 | #include <sys/ioctl.h> | |
37 | #include <netinet/in.h> | |
38 | #include <netdb.h> | |
39 | #include <errno.h> | |
a4fafd85 | 40 | #ifdef SOLARIS |
41 | #include <sys/filio.h> | |
42 | #endif /* SOLARIS */ | |
d9f43d51 | 43 | #ifdef POSIX |
44 | #include <unistd.h> | |
45 | #endif | |
5580185e | 46 | |
47 | extern int errno; | |
5580185e | 48 | |
49 | CONNECTION gdb_allocate_connection(); | |
50 | ||
8fd777cf | 51 | /************************************************************************ |
52 | * | |
53 | * start_peer_connection (start_peer_connection) | |
54 | * | |
55 | * Starts a connection to another process which itself will be | |
56 | * issuing a start_peer_connection to us. Current implementation | |
57 | * builds at most one stream, with the risk of a hang if | |
58 | * the attempts to connect cross in the night. This is a bug, | |
59 | * but this level of support is acceptable for casual debugging | |
60 | * of applications, and perhaps for some production use in | |
61 | * controlled settings. I think the only other way to do it | |
62 | * is to risk building two streams in parallel, possibly tearing | |
63 | * one down when the duplication is discovered. Seems complicated | |
64 | * and messy. | |
65 | * | |
66 | ************************************************************************/ | |
5580185e | 67 | |
68 | CONNECTION | |
69 | start_peer_connection(id) | |
70 | char *id; /* null terminated string */ | |
71 | { | |
72 | register CONNECTION con; /* the connection we're */ | |
73 | /* creating */ | |
74 | ||
75 | GDB_INIT_CHECK | |
76 | ||
77 | /* | |
78 | * Try to allocate a connection and fill it in with null values. | |
79 | */ | |
80 | ||
81 | con = g_make_con(); | |
82 | ||
83 | /* | |
84 | * In this implementation, we use a single fd for both inbound and | |
85 | * outbound traffic. Try to connect to other side. If that | |
86 | * doesn't work, wait to accept a connection from the other side. | |
87 | * Current implementation of this is synchronous--may be a problem? | |
88 | * Also note timing window bug in the following. If the two peers | |
89 | * are started at just about the same time, the race may not be handled | |
90 | * propoerly. If the connections come up, then verify the level of | |
91 | * protocol being observed on the connections. If incompatible, | |
92 | * then turn off the connection. | |
93 | */ | |
94 | ||
95 | if(!g_try_connecting(con,id)) { | |
96 | g_try_accepting(con,id); | |
97 | if(con->status == CON_STARTING) | |
98 | g_ver_iprotocol(con); | |
99 | } else | |
100 | if(con->status == CON_STARTING) | |
101 | g_ver_oprotocol(con); | |
102 | ||
103 | ||
104 | if (con->status == CON_UP) { | |
105 | /* | |
106 | * We've successfully started the connection, now mark | |
107 | * it for non-blocking I/O. Also, update the high water | |
108 | * mark of fd's controlled by our system. | |
109 | */ | |
110 | int nb = 1; | |
111 | if(ioctl(con->in.fd, FIONBIO, (char *)&nb)== (-1)) { | |
112 | g_stop_with_errno(con); | |
113 | return con; | |
114 | } | |
115 | if (con->in.fd +1 > gdb_mfd) | |
116 | gdb_mfd = con->in.fd + 1; | |
117 | /* | |
118 | * Allocate a buffer, if necessary, and reset buffer pointers | |
119 | * so first request will result in a long read into the buffer | |
120 | */ | |
121 | g_allocate_connection_buffers(con); | |
122 | ||
123 | return con; | |
124 | } else | |
125 | return NULL; | |
126 | } | |
8fd777cf | 127 | |
128 | ||
5580185e | 129 | /************************************************************************/ |
130 | /* | |
131 | /* g_make_con | |
132 | /* | |
133 | /* Internal routine to allocate a new connection structure and | |
134 | /* initialize all its fields to logical null values. | |
135 | /* | |
136 | /************************************************************************/ | |
137 | ||
138 | CONNECTION | |
139 | g_make_con() | |
140 | { | |
141 | register CONNECTION con; | |
142 | ||
143 | /* | |
144 | * Try to allocate a connection, fatal error if none available | |
145 | */ | |
146 | con = gdb_allocate_connection(); | |
147 | if (con == NULL) | |
148 | GDB_GIVEUP("start_peer_connection: Tried to allocate too many connections") /* <==RECOVERABLE */ | |
149 | ||
150 | /* | |
151 | * Give the fields their initial values | |
152 | */ | |
153 | g_null_con(con); | |
154 | ||
155 | return con; | |
156 | ||
157 | } | |
158 | ||
8fd777cf | 159 | |
160 | /************************************************************************/ | |
5580185e | 161 | /* |
162 | /* g_null_con | |
163 | /* | |
164 | /* Sets a connection descriptor to have all null values in | |
165 | /* its fields. This routine does NOT do any of the cleanup | |
166 | /* which is necessary after the connection has really been used. | |
167 | /* | |
168 | /************************************************************************/ | |
169 | ||
170 | int | |
171 | g_null_con(con) | |
172 | CONNECTION con; | |
173 | { | |
174 | /* | |
175 | * Initialize the connection control data structure. | |
176 | */ | |
177 | con->id = GDB_CON_ID; | |
178 | con->status = CON_STARTING; | |
179 | con->oob_fcn = NULL; /* out of band signalling */ | |
180 | /* is not currently */ | |
181 | /* implemented */ | |
182 | con->errno = 0; /* system errno gets */ | |
183 | /* copied here iff it */ | |
184 | /* causes this con to die */ | |
185 | /* | |
186 | * Initialize input half connection to null state before trying | |
187 | * to bring it up. | |
188 | */ | |
189 | con->in.status = OP_NOT_STARTED; | |
190 | con->in.fd = -1; | |
191 | con->in.oob_fd = -1; | |
192 | con->in.op_q_first = (struct oper_data *)&con->in; | |
193 | con->in.op_q_last = (struct oper_data *)&con->in; | |
194 | con->in.next_byte = NULL; | |
195 | con->in.remaining = 0; | |
196 | con->in.flags = 0; | |
197 | ||
198 | /* | |
199 | * Initialize output half connection to null state before trying | |
200 | * to bring it up. | |
201 | */ | |
202 | con->out.status = OP_NOT_STARTED; | |
203 | con->out.fd = -1; | |
204 | con->out.oob_fd = -1; | |
205 | con->out.op_q_first = (struct oper_data *)&con->out; | |
206 | con->out.op_q_last = (struct oper_data *)&con->out; | |
207 | con->out.next_byte = NULL; | |
208 | con->out.remaining = 0; | |
209 | con->out.flags = 0; | |
210 | ||
211 | return; | |
212 | ||
213 | } | |
214 | ||
8fd777cf | 215 | |
5580185e | 216 | /************************************************************************/ |
217 | /* | |
218 | /* gdb_allocate_connection | |
219 | /* | |
220 | /* Return an unused entry in the connection array. Unused entries | |
221 | /* are recognized by being marked as CON_STOPPED. | |
222 | /* | |
223 | /* Note that gdb_mcons is the number of descriptors which have | |
224 | /* ever been used (i.e. a high water mark), so status fields | |
225 | /* are invalid above that. | |
226 | /* | |
227 | /************************************************************************/ | |
228 | ||
229 | CONNECTION | |
230 | gdb_allocate_connection() | |
231 | { | |
232 | register int i; /* index of next one */ | |
233 | /* to check */ | |
234 | ||
235 | /* | |
236 | * First look for one below the high water mark | |
237 | */ | |
238 | for(i=0; i<gdb_mcons; i++) { | |
239 | if (gdb_cons[i].status == CON_STOPPED) | |
240 | return &gdb_cons[i]; | |
241 | } | |
242 | ||
243 | /* | |
244 | * Allocate one which has never been used, if possible | |
245 | */ | |
246 | ||
247 | if (i>=GDB_MAX_CONNECTIONS) | |
248 | GDB_GIVEUP("gdb: tried to allocate too many simulataneous connections.\n, See GDB_MAX_CONNECTIONS in gdb.h.") /* <==RECOVERABLE */ | |
249 | ||
250 | gdb_mcons++; /* bump the high water mark */ | |
251 | gdb_cons[i].status = CON_STOPPED; /* initialize status of the */ | |
252 | /* new connection */ | |
253 | return &gdb_cons[i]; /* return new highest con */ | |
254 | /* ever used*/ | |
255 | } | |
8fd777cf | 256 | |
257 | ||
5580185e | 258 | /************************************************************************/ |
259 | /* | |
260 | /* g_try_connecting | |
261 | /* | |
262 | /* Try to start a connection to the designated site, filling | |
263 | /* in the appropriate information in the connection descriptor | |
264 | /* if successful. Return TRUE if connection succeeded or if | |
265 | /* error was fatal enough that we shouldn't try accepting. Returns | |
266 | /* FALSE if we should try accepting. | |
267 | /* | |
268 | /************************************************************************/ | |
269 | ||
270 | int | |
271 | ||
272 | g_try_connecting(con,id) | |
273 | CONNECTION con; | |
274 | char *id; | |
275 | { | |
276 | int peer; /* socket for talking to | |
277 | peer */ | |
98a7b0ee | 278 | char on = 1; /* flag for ioctl */ |
5580185e | 279 | struct sockaddr_in target; /* build the peer address */ |
280 | /* here */ | |
281 | struct hostent *peer_host; /* host where peer is */ | |
282 | ||
283 | /*----------------------------------------------------------*/ | |
284 | /* | |
285 | /* Make sure connection is marked stopped until we | |
286 | /* get it going. | |
287 | /* | |
288 | /*----------------------------------------------------------*/ | |
289 | ||
290 | con->status = CON_STOPPED; | |
291 | ||
292 | /*----------------------------------------------------------*/ | |
293 | /* | |
294 | /* Find out host where peer is, and validate it. Take | |
295 | /* care of port at the same time. | |
296 | /* | |
297 | /*----------------------------------------------------------*/ | |
298 | ||
8fd777cf | 299 | memset((char *)&target, 0, sizeof(target)); |
5580185e | 300 | g_parse_target(id, &peer_host, &target.sin_port); |
301 | if (peer_host == NULL) { | |
302 | fprintf(gdb_log,"gdb: g_try_connecting... '%s' is not a valid host:server\n", | |
303 | id); | |
304 | return TRUE; /* so we won't try accepting */ | |
305 | } | |
306 | ||
307 | /*----------------------------------------------------------*/ | |
308 | /* | |
309 | /* Create a socket | |
310 | /* | |
311 | /*----------------------------------------------------------*/ | |
312 | ||
313 | peer = socket(AF_INET, SOCK_STREAM, 0); | |
314 | if (peer < 0) { | |
315 | g_stop_with_errno(con); | |
316 | return TRUE; /* fatal error */ | |
317 | } | |
318 | ||
319 | /*----------------------------------------------------------*/ | |
320 | /* | |
321 | /* Get information and bind socket using well known | |
322 | /* port (BUG: this restricts us to one pair of peers | |
323 | /* per host pair, as well as being bad practice on | |
324 | /* the network. It will do for debugging. | |
325 | /* | |
326 | /*----------------------------------------------------------*/ | |
327 | ||
328 | ||
8fd777cf | 329 | memcpy((char *)&target.sin_addr,peer_host->h_addr,peer_host->h_length); |
5580185e | 330 | target.sin_family = peer_host->h_addrtype; |
331 | ||
332 | /*----------------------------------------------------------*/ | |
333 | /* | |
334 | /* Make the connection | |
335 | /* | |
336 | /*----------------------------------------------------------*/ | |
337 | ||
338 | if(connect(peer, (struct sockaddr *)&target, sizeof(target)) < 0) { | |
339 | if (errno == ECONNREFUSED) | |
340 | return FALSE; /* other side not yet */ | |
341 | /* up, but no other fatal */ | |
342 | /* errors*/ | |
343 | else { | |
344 | gdb_perror("gdb: unexpected error connecting"); | |
345 | g_stop_with_errno(con); | |
346 | return TRUE; | |
347 | } | |
348 | } | |
349 | ||
a72ae0b9 | 350 | if ((gdb_Options & GDB_OPT_KEEPALIVE) && |
351 | setsockopt(peer, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) { | |
352 | gdb_perror("gdb: unable to start keepalives"); | |
353 | g_stop_with_errno(con); | |
354 | return(TRUE); | |
355 | } | |
356 | ||
5580185e | 357 | /*----------------------------------------------------------*/ |
358 | /* | |
359 | /* The connection has been made, fill in the connection | |
360 | /* control data structure. | |
361 | /* | |
362 | /*----------------------------------------------------------*/ | |
363 | ||
364 | con->in.fd = peer; | |
365 | con->out.fd = peer; | |
366 | con->status = CON_STARTING; | |
367 | ||
368 | return TRUE; | |
369 | ||
370 | } | |
8fd777cf | 371 | |
372 | ||
5580185e | 373 | /************************************************************************/ |
374 | /* | |
375 | /* g_parse_target | |
376 | /* | |
377 | /* For a given server or peer i.d., figure out the host and the | |
378 | /* port. Arguments are: | |
379 | /* | |
380 | /* string i.d. of the server, which is | |
381 | /* in one of two forms: | |
382 | /* | |
383 | /* host:servicename (where service name must not begin | |
384 | /* with #) | |
385 | /* | |
386 | /* host:#portnumber (where portnumber is the actual | |
387 | /* number of the port to be used) | |
388 | /* | |
389 | /* (actually, a 3rd form, with no port number supplied, | |
390 | /* will use a default GDB_PORT, but this is unsafe | |
391 | /* and it will be disabled in production versions | |
392 | /* of the gdb system.) | |
393 | /* | |
394 | /* **hostent: returned to indicate host to be used. Null | |
395 | /* if host could not be found | |
396 | /* | |
397 | /* *port pointer to an integer where the port number will | |
398 | /* be put. We return the port number in network | |
399 | /* byte order. | |
400 | /* | |
401 | /************************************************************************/ | |
402 | ||
403 | int | |
404 | g_parse_target(id, host, port) | |
405 | char *id; | |
406 | struct hostent **host; | |
407 | u_short *port; | |
408 | { | |
409 | char buffer[256]; /* longest host name */ | |
410 | register char *ip, *bp; /* for copying name */ | |
411 | struct servent *serv; /* returned from */ | |
412 | /* get service by name */ | |
413 | ||
414 | /*----------------------------------------------------------*/ | |
415 | /* | |
416 | /* copy the host name part only to local buffer | |
417 | /* | |
418 | /*----------------------------------------------------------*/ | |
419 | ||
420 | ip = id; | |
421 | bp = buffer; | |
422 | ||
423 | while (*ip != '\0' && *ip != ':') | |
424 | *bp++ = *ip++; | |
425 | *bp = '\0'; | |
426 | ||
427 | /*----------------------------------------------------------*/ | |
428 | /* | |
429 | /* Look up the host name, return if bad. | |
430 | /* | |
431 | /*----------------------------------------------------------*/ | |
432 | ||
433 | *host = gethostbyname(buffer); | |
434 | ||
435 | if (*host == NULL) | |
436 | return; | |
437 | ||
438 | /*----------------------------------------------------------*/ | |
439 | /* | |
440 | /* Set up the port address | |
441 | /* | |
442 | /*----------------------------------------------------------*/ | |
443 | ||
444 | if (*ip++ != ':') { | |
445 | *port = GDB_PORT; | |
446 | return; | |
447 | } | |
448 | ||
449 | if (*ip == '\0') { | |
450 | *host = NULL; | |
451 | return; | |
452 | } | |
453 | ||
454 | if (*ip == '#') { | |
455 | /* | |
456 | * port number supplied explictly | |
457 | */ | |
458 | ip++; | |
459 | if (*ip < '0' || *ip>'9') { | |
460 | *host = NULL; | |
461 | return; | |
462 | } | |
463 | *port = htons((u_short)atoi(ip)); | |
464 | } else { | |
465 | /* | |
466 | * service identified by name | |
467 | */ | |
468 | serv = getservbyname(ip, "tcp"); | |
469 | if (serv == NULL) { | |
470 | *host = NULL; | |
471 | return; | |
472 | } | |
473 | *port = serv->s_port; | |
474 | } | |
475 | } | |
8fd777cf | 476 | |
477 | ||
5580185e | 478 | /************************************************************************/ |
479 | /* | |
480 | /* g_try_accepting | |
481 | /* | |
482 | /* Try to accept a connection to the designated site, filling | |
483 | /* in the appropriate information in the connection descriptor | |
484 | /* if successful. | |
485 | /* | |
486 | /************************************************************************/ | |
487 | ||
488 | int | |
489 | g_try_accepting(con,id) | |
490 | CONNECTION con; | |
491 | char *id; | |
492 | { | |
493 | int slisten; /* socket on which | |
494 | we listen for connections */ | |
495 | ||
496 | int peer; /* socket for talking to | |
497 | peer */ | |
498 | int fromlen; | |
499 | struct sockaddr_in self, from; | |
500 | int retries = GDB_BIND_RETRY_COUNT; | |
501 | int onoff = 1; /* used as argument to */ | |
502 | /* setsockopt */ | |
503 | ||
504 | struct hostent *peer_host; /* host where peer is */ | |
505 | ||
506 | /*----------------------------------------------------------*/ | |
507 | /* | |
508 | /* Make sure connection is marked stopped until we | |
509 | /* get it going. | |
510 | /* | |
511 | /*----------------------------------------------------------*/ | |
512 | ||
513 | con->status = CON_STOPPED; | |
514 | ||
515 | /*----------------------------------------------------------*/ | |
516 | /* | |
517 | /* Create a socket on which to listen. Tell it that | |
518 | /* it's OK to re-use the port address, which may still | |
519 | /* appear busy if connections are taking awhile to go | |
520 | /* away. | |
521 | /* | |
522 | /*----------------------------------------------------------*/ | |
523 | ||
524 | slisten = socket(AF_INET, SOCK_STREAM, 0); | |
525 | if (slisten < 0) { | |
526 | gdb_perror("g_try_accepting: error creating listen socket"); | |
527 | g_stop_with_errno(con); | |
528 | } | |
529 | /* Try 4.2 method */ | |
530 | if(setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, (char *)0, 0)<0) | |
531 | /* that didn't work, try 4.3 */ | |
532 | if(setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, | |
533 | (char *)&onoff, sizeof(int)) <0) | |
534 | GDB_GIVEUP("g_try_accepting: could not set SO_REUSEADDR"); | |
535 | ||
536 | /*----------------------------------------------------------*/ | |
537 | /* | |
538 | /* Find out host where peer is, and validate it. Take | |
539 | /* care of port at the same time. This is redundant | |
540 | /* given that g_try_connecting is always called first. | |
541 | /* | |
542 | /*----------------------------------------------------------*/ | |
543 | ||
8fd777cf | 544 | memset((char *)&self, 0, sizeof(self)); |
5580185e | 545 | g_parse_target(id, &peer_host, &self.sin_port); |
546 | if (peer_host == NULL) { | |
547 | GDB_GIVEUP("gdb_try_accepting: bad port not caught by try connecting") | |
548 | } | |
549 | ||
550 | /*----------------------------------------------------------*/ | |
551 | /* | |
552 | /* Bind the socket to ourselves, using the well known | |
553 | /* port (See bug note in g_try_connecting. | |
554 | /* | |
555 | /* This code should really go in initialization, I think. | |
556 | /* | |
557 | /*----------------------------------------------------------*/ | |
558 | ||
559 | while (bind(slisten,(struct sockaddr *)&self,sizeof(self)) < 0) { | |
560 | if (errno == EADDRINUSE && retries--) { | |
561 | fprintf(gdb_log,"gdb: port address in use, will retry %d more time(s)\n",retries+1); | |
562 | sleep(GDB_BIND_RETRY_INTERVAL); | |
563 | continue; | |
564 | } else { | |
565 | gdb_perror("gdb: error binding listen socket"); | |
566 | g_stop_with_errno(con); | |
567 | (void) close(slisten); | |
568 | return; | |
569 | } | |
570 | } | |
571 | ||
572 | /*----------------------------------------------------------*/ | |
573 | /* | |
574 | /* Listen for connections. | |
575 | /* | |
576 | /*----------------------------------------------------------*/ | |
577 | ||
578 | (void) listen (slisten, 5); /* does not block, just */ | |
579 | /* sets the maximum backlog */ | |
580 | /* of pending non-accepted */ | |
581 | /* cons.*/ | |
582 | fromlen = sizeof(from); | |
d9f43d51 | 583 | peer = accept(slisten, (struct sockaddr *)&from, &fromlen); |
5580185e | 584 | if (peer < 0) { |
585 | g_stop_with_errno(con); | |
586 | gdb_perror("gdb_try_accepting: error accepting connection"); | |
587 | (void) close(slisten); | |
588 | return; | |
589 | } | |
590 | ||
591 | (void) close (slisten); /* we're not using the */ | |
592 | /* listening socket */ | |
593 | /* anymore, only the */ | |
594 | /* connection to the peer */ | |
595 | ||
596 | /*----------------------------------------------------------*/ | |
597 | /* | |
598 | /* The connection has been made, fill in the connection | |
599 | /* control data structure. | |
600 | /* | |
601 | /*----------------------------------------------------------*/ | |
602 | ||
603 | con->in.fd = peer; | |
604 | con->out.fd = peer; | |
605 | con->status = CON_STARTING; | |
606 | } | |
8fd777cf | 607 | |
608 | ||
5580185e | 609 | /************************************************************************/ |
610 | /* | |
611 | /* g_ver_oprotocol | |
612 | /* | |
613 | /* Called when an outbound connection is started to verify | |
614 | /* the version of the protocol being observed. | |
615 | /* | |
616 | /************************************************************************/ | |
617 | ||
618 | int | |
619 | g_ver_oprotocol(con) | |
620 | CONNECTION con; | |
621 | { | |
622 | #ifdef VERIFY_PROTOCOL | |
623 | char ver = GDB_PROTOCOL_VERSION; | |
624 | char theirs; | |
625 | int len; | |
626 | ||
627 | int onoff = 0; /* for ioctl to turn off */ | |
628 | ||
629 | /* | |
630 | * Because the connection was accepted on a non-blocking | |
631 | * listening socket, the connection itself may be non-blocking. | |
632 | * We can't tolerate that here. It will be reset later. | |
633 | */ | |
634 | if (ioctl(con->in.fd, FIONBIO, (char *)&onoff) < 0) { | |
635 | g_stop_with_errno(con); | |
636 | gdb_perror("Can't turn off FIONBIO in g_ver_iprotocol"); | |
637 | return; | |
638 | } | |
639 | ||
640 | while (write(con->out.fd, &ver, 1) < 0) { | |
641 | g_stop_with_errno(con); | |
642 | return; | |
643 | } | |
644 | ||
645 | do { | |
646 | len = read(con->in.fd, &theirs, 1); | |
647 | if (len == (-1)) { | |
648 | g_stop_with_errno(con); | |
649 | return; | |
650 | } | |
651 | } while (len !=1); | |
652 | ||
653 | if (theirs == ver) | |
654 | con->status = CON_UP; | |
655 | else | |
656 | con->status = CON_STOPPED; | |
d9f43d51 | 657 | #else |
5580185e | 658 | con->status = CON_UP; |
d9f43d51 | 659 | #endif |
5580185e | 660 | } |
661 | ||
8fd777cf | 662 | |
5580185e | 663 | /************************************************************************/ |
664 | /* | |
665 | /* g_ver_iprotocol | |
666 | /* | |
667 | /* Called when an inbound connection is started to verify | |
668 | /* the version of the protocol being observed. | |
669 | /* | |
670 | /************************************************************************/ | |
671 | ||
672 | int | |
673 | g_ver_iprotocol(con) | |
674 | CONNECTION con; | |
675 | { | |
676 | #ifdef VERIFY_PROTOCOL | |
677 | char ver = GDB_PROTOCOL_VERSION; | |
678 | char theirs; | |
679 | int len; | |
680 | int old_nbio; | |
681 | int onoff = 0; /* for ioctl to turn off */ | |
682 | ||
683 | /* | |
684 | * Because the connection was accepted on a non-blocking | |
685 | * listening socket, the connection itself may be non-blocking. | |
686 | * We can't tolerate that here. It will be reset later. | |
687 | */ | |
688 | if (ioctl(con->in.fd, FIONBIO, (char *)&onoff) < 0) { | |
689 | g_stop_with_errno(con); | |
690 | gdb_perror("Can't turn off FIONBIO in g_ver_iprotocol"); | |
691 | return; | |
692 | } | |
693 | ||
694 | do { | |
695 | len = read(con->in.fd, &theirs, 1); | |
696 | if (len == (-1)) { | |
697 | g_stop_with_errno(con); | |
698 | return; | |
699 | } | |
700 | } while (len !=1) ; | |
701 | ||
702 | if (theirs == ver) | |
703 | con->status = CON_UP; | |
704 | else | |
705 | con->status = CON_STOPPED; | |
706 | ||
707 | while (write(con->out.fd, &ver, 1) < 0) { | |
708 | g_stop_with_errno(con); | |
709 | return; | |
710 | } | |
d9f43d51 | 711 | #else |
5580185e | 712 | con->status = CON_UP; |
713 | #endif | |
714 | } | |
715 | ||
8fd777cf | 716 | |
5580185e | 717 | /************************************************************************/ |
718 | /* | |
719 | /* sever_connection (sever_connection) | |
720 | /* | |
721 | /* Unconditionally, but cleanly, terminates a connection. All | |
722 | /* pending operations on the connection are cancelled, and the | |
723 | /* file descriptor for the connection is closed. This routine | |
724 | /* should be called directly from applications wishing to shut | |
725 | /* down a connection. No transmissions are attempted | |
726 | /* by this routine. Returns NULL, in the hope that applications | |
727 | /* will assign this to their old CONNECTION variable. | |
728 | /* | |
729 | /************************************************************************/ | |
730 | ||
731 | CONNECTION | |
732 | sever_connection(con) | |
733 | CONNECTION con; | |
734 | { | |
735 | if (con == NULL) | |
736 | return NULL; | |
737 | GDB_CHECK_CON(con, "sever_connection") | |
738 | if (con->status == CON_UP || con->status == CON_STARTING) | |
739 | g_stop_connection(con); | |
740 | if (con->status != CON_STOPPED) | |
741 | gdb_de_allocate_connection(con); | |
742 | ||
743 | return NULL; | |
744 | } | |
745 | ||
8fd777cf | 746 | |
5580185e | 747 | /************************************************************************/ |
748 | /* | |
749 | /* g_stop_with_errno | |
750 | /* | |
751 | /* This connection is stopping because of a problem on a syscall. | |
752 | /* We record the errno in the connection descriptor for inspection | |
753 | /* by the application, then stop the connection. | |
754 | /* | |
755 | /************************************************************************/ | |
756 | ||
5580185e | 757 | int |
758 | g_stop_with_errno(con) | |
759 | CONNECTION con; | |
760 | { | |
761 | con->errno = errno; | |
762 | g_stop_connection(con); | |
763 | ||
764 | } | |
765 | ||
8fd777cf | 766 | |
5580185e | 767 | /************************************************************************/ |
768 | /* | |
769 | /* g_stop_connection | |
770 | /* | |
771 | /* Unconditionally, but cleanly, terminates a connection. All | |
772 | /* pending operations on the connection are cancelled, and the | |
773 | /* file descriptor for the connection is closed. This routine is | |
774 | /* for internal use. Applications call sever_connection, which | |
775 | /* also de_allocates the descriptor. No transmissions are attempted | |
776 | /* by this routine. | |
777 | /* | |
778 | /************************************************************************/ | |
779 | ||
780 | int | |
781 | g_stop_connection(con) | |
782 | CONNECTION con; | |
783 | { | |
784 | /* | |
785 | * Shutdown activity on the two half connections. | |
786 | */ | |
787 | g_cleanup_half_connection(&(con->in)); | |
788 | g_cleanup_half_connection(&(con->out)); | |
789 | ||
790 | /* | |
791 | * Remove the file descriptor from the select bit maps | |
792 | */ | |
e3b289f4 | 793 | if (!(con->in.flags & HCON_UNUSED) && con->in.fd >= 0) |
5580185e | 794 | FD_CLR(con->in.fd, &gdb_crfds); |
e3b289f4 | 795 | if (!(con->out.flags & HCON_UNUSED) && con->out.fd >= 0) |
5580185e | 796 | FD_CLR(con->out.fd, &gdb_cwfds); |
797 | /* | |
798 | * Close the file descriptor. Note, this presumes that in fact | |
799 | * 1) in is never the unused half and | |
800 | * 2) when the connection is bi-directional, in and out share an | |
801 | * fd. We could do with a more elaborate scheme to control | |
802 | * this in the future. | |
803 | */ | |
804 | (void) close(con->in.fd); | |
805 | ||
806 | /* | |
807 | * Mark the connection as stopping. We can't reclaim the | |
808 | * descriptor until the application does a sever, or else there | |
809 | * would be a risk of re-allocating it out from under the application. | |
810 | */ | |
811 | ||
812 | con->status = CON_STOPPING; | |
813 | ||
814 | return; | |
815 | } | |
816 | ||
8fd777cf | 817 | |
5580185e | 818 | /************************************************************************/ |
819 | /* | |
820 | /* gdb_de_allocate_connection | |
821 | /* | |
822 | /* Return a connection whose file descriptors have been closed | |
823 | /* to the pool. | |
824 | /* | |
825 | /************************************************************************/ | |
826 | ||
827 | int | |
828 | gdb_de_allocate_connection(con) | |
829 | CONNECTION con; | |
830 | { | |
831 | register int i; | |
832 | ||
833 | con->status = CON_STOPPED; | |
834 | ||
835 | i = gdb_mcons-1; /* start at last one used */ | |
836 | ||
837 | /* | |
838 | * Reset gdb_mcons to be the number of connections in use | |
839 | */ | |
840 | while (i>=0 && gdb_cons[i].status == CON_STOPPED) | |
841 | i--; | |
842 | ||
843 | gdb_mcons = i + 1; | |
844 | } | |
8fd777cf | 845 | |
846 | ||
5580185e | 847 | /************************************************************************/ |
848 | /* | |
849 | /* g_cleanup_half_conection | |
850 | /* | |
851 | /* Terminate all pending operations on the supplied half | |
852 | /* connection. Note that the algorithm used here presumes | |
853 | /* that cancel_operation will de-queue the operation descriptor, | |
854 | /* therefore we have to be careful here about when we look at | |
855 | /* chain pointers. | |
856 | /* | |
857 | /************************************************************************/ | |
858 | ||
859 | int | |
860 | g_cleanup_half_connection(hcon) | |
861 | HALF_CONNECTION hcon; | |
862 | { | |
863 | OPERATION current, next; | |
864 | ||
865 | current = hcon->op_q_first; | |
866 | ||
867 | /* | |
868 | * Loop through all operations in the queue canceling them. | |
869 | * Make sure to pick up pointer to 'next' before the current | |
870 | * one is canceled, as cancelling may invalidate the pointer. | |
871 | */ | |
872 | ||
873 | while (current != (OPERATION)hcon) { | |
874 | next = current->next; | |
875 | (void) cancel_operation(current); | |
876 | current = next; | |
877 | } | |
878 | } | |
8fd777cf | 879 | |
880 | ||
5580185e | 881 | /************************************************************************/ |
882 | /* | |
883 | /* create_listening_connection (create_listening_connection) | |
884 | /* | |
885 | /* Starts a special type of connection which is used to listen | |
886 | /* for incoming connection requests. The inbound half-connection | |
887 | /* is the only one used for this special kind of connection. | |
888 | /* | |
889 | /* It is the user's responsibility to insure that only appropriate | |
890 | /* types of operation are queued on a connection of this sort. In | |
891 | /* general, these connections are intended for internal use by | |
892 | /* GDB, and they are not intended to be visible to servers or | |
893 | /* clients directly. | |
894 | /* | |
895 | /* The id supplied should be in one of two forms. If just a | |
896 | /* string is supplied then it is presumed to be the name of | |
897 | /* a registered tcp service. If the name begins with a #, then | |
898 | /* the rest is interpreted as the integer port number to be used. | |
899 | /* | |
900 | /* In future implementations, the id may have more structure, which | |
901 | /* is why we define it as a string. | |
902 | /* | |
903 | /************************************************************************/ | |
904 | ||
905 | CONNECTION | |
906 | create_listening_connection(id) | |
907 | char *id; | |
908 | { | |
909 | register CONNECTION con; /* the connection we're */ | |
910 | /* creating */ | |
911 | ||
912 | register int slisten; /* socket on which | |
913 | we listen for connections */ | |
914 | ||
915 | struct sockaddr_in self; | |
916 | int retries = GDB_BIND_RETRY_COUNT; | |
917 | int onoff = 1; /* used as argument to */ | |
918 | /* setsockopt */ | |
919 | struct servent *serv; | |
920 | ||
921 | GDB_INIT_CHECK | |
922 | ||
923 | /* | |
924 | * Try to allocate a connection and fill it in with null values. | |
925 | */ | |
926 | ||
927 | con = g_make_con(); | |
928 | ||
929 | /* | |
930 | * Try to create a socket for listening | |
931 | */ | |
932 | con->in.fd = socket(AF_INET, SOCK_STREAM, 0); | |
933 | slisten = con->in.fd; /* easier and faster than */ | |
934 | /* using con->in.fd all the */ | |
935 | /* time*/ | |
936 | if (slisten < 0 ) { | |
937 | gdb_perror("create_listening_connection: error creating listen socket"); | |
938 | (void) g_stop_with_errno(con); | |
939 | return con; | |
940 | } | |
941 | /* | |
942 | * Set options so the listening address can be re-used (this | |
943 | * has its dangers, but otherwise we can't restart our servers | |
944 | * for long periods after they crash because of connections which | |
945 | * take a long to time clean up and hold ports in use.) | |
946 | */ | |
947 | ||
948 | /* Try 4.2 method */ | |
949 | if(setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, (char *)0,0)<0) | |
950 | /* that didn't work, try 4.3 */ | |
951 | if(setsockopt(slisten, SOL_SOCKET, SO_REUSEADDR, | |
952 | (char *)&onoff, sizeof(int)) <0) | |
953 | GDB_GIVEUP("create_listening_connection: could not set SO_REUSEADDR") | |
954 | ; | |
955 | /* | |
956 | * Make the listening socket non-blocking so we won't have to do | |
957 | * selects before polling it (change made by Bill Sommerfeld - wesommer) | |
958 | */ | |
959 | if (ioctl(slisten, FIONBIO, (char *)&onoff) < 0) { /*<==FIX,,,add comment */ | |
960 | g_stop_with_errno(con); | |
961 | gdb_perror("ioctl for listening socket"); | |
962 | return con; | |
963 | } | |
964 | /*----------------------------------------------------------*/ | |
965 | /* | |
966 | /* Bind the socket to ourselves, using port derived from | |
967 | /* the supplied id string. | |
968 | /* | |
969 | /*----------------------------------------------------------*/ | |
970 | ||
8fd777cf | 971 | memset((char *)&self, 0, sizeof(self)); |
5580185e | 972 | /* |
973 | * Determine our port number | |
974 | */ | |
975 | if (*id == '#') | |
976 | self.sin_port = htons((u_short)atoi(id+1)); | |
977 | else { | |
978 | serv = getservbyname(id, "tcp"); | |
979 | if (serv == NULL) { | |
980 | fprintf(gdb_log,"gdb create_listening_connection: cannot become service named %s\n",id); | |
981 | return NULL; /* BUG: causes connetion */ | |
982 | /* descriptor leakage. Should */ | |
983 | /* return an error code in */ | |
984 | /* the connection descriptor*/ | |
985 | } | |
986 | self.sin_port = serv->s_port; | |
987 | ||
988 | } | |
989 | /* | |
990 | * Try and re-try the bind until it works or until retry count | |
991 | * is exhausted. | |
992 | */ | |
993 | while (bind(slisten,(struct sockaddr *)&self,sizeof(self)) < 0) { | |
994 | if (errno == EADDRINUSE && retries--) { | |
995 | fprintf(gdb_log,"gdb create_listening_connection: port address in use, will retry %d more time(s)\n",retries+1); | |
996 | sleep(GDB_BIND_RETRY_INTERVAL); | |
997 | continue; | |
998 | } else { | |
999 | gdb_perror("gdb create_listening_connection: error binding listen socket"); | |
1000 | g_stop_with_errno(con); | |
1001 | return con; | |
1002 | } | |
1003 | } | |
1004 | ||
1005 | /*----------------------------------------------------------*/ | |
1006 | /* | |
1007 | /* Listen for connections. | |
1008 | /* | |
1009 | /*----------------------------------------------------------*/ | |
1010 | ||
1011 | (void) listen (slisten, 5); /* does not block, just */ | |
1012 | /* sets the maximum backlog */ | |
1013 | /* of pending non-accepted */ | |
1014 | /* cons.*/ | |
1015 | ||
1016 | con->in.flags |= HCON_LISTEN; | |
1017 | con->out.flags |= HCON_UNUSED; | |
1018 | con->status = CON_UP; | |
1019 | if (con->in.fd +1 > gdb_mfd) | |
1020 | gdb_mfd = con->in.fd + 1; | |
1021 | return con; | |
1022 | } | |
8fd777cf | 1023 | |
1024 | ||
5580185e | 1025 | /************************************************************************/ |
1026 | /* | |
1027 | /* g_allocate_connection_buffers | |
1028 | /* | |
1029 | /* Create a buffer which can be used to receive large | |
1030 | /* chunks of data from the socket. This is currently done only | |
1031 | /* on the inbound half connection. Also, the buffers are not freed | |
1032 | /* once allocated, even if the connection descriptor is re-used. | |
1033 | /* | |
1034 | /************************************************************************/ | |
1035 | ||
1036 | int | |
1037 | g_allocate_connection_buffers(con) | |
1038 | CONNECTION con; | |
1039 | { | |
1040 | HALF_CONNECTION inbound = &(con->in); | |
1041 | ||
1042 | /* | |
1043 | * See if there is already one allocated, if not, allocate one. | |
1044 | */ | |
1045 | if (inbound->stream_buffer == (char *)NULL) { | |
1046 | inbound->stream_buffer = | |
1047 | db_alloc(inbound->stream_buffer_length); | |
1048 | } | |
1049 | ||
1050 | /* | |
1051 | * In any case, make sure that it is effectively empty | |
1052 | */ | |
1053 | inbound -> stream_buffer_next = inbound -> stream_buffer; | |
1054 | inbound -> stream_buffer_remaining = 0; | |
1055 | } |