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