next up previous contents
Next: 7.5 Parcel Sublayer Up: 7 Source Code Presentation Previous: 7.3 Application Programmers Interface:

7.4 User Space Implementation: XUDP Daemon

 

7.4.1 main()

 1 void main()
 2 {
 3     struct XUDPCB  *xudpcb;
 4     struct XUDPSCB *xudpscb;
 5     struct XUDPCmd *pCmd;
 6     int            pidChild;
 7     fd_set         setFD;
 8     int            result;
 9     struct timeval timestuff;
10     Timestamp      ts;
11     Boolean        dontwait=FALSE;
12 #ifdef STATLOG
13     Timestamp      statts=0;
14 #endif
15     printf("xudpd: eXtended User Datagram Protocol handler\n");
16     printf("[Initializing...");
17     fflush(stdout);
18 
19     if ( !(xudpscb=malloc(sizeof(struct XUDPSCB))))
20         xudpError("xudpd: Allocating RAM");
21     
22     xudp_init(xudpscb);
23 
24     printf("ok]\n");
25     fflush(stdout);
26 
27     while(1) /* Loop "forever" */
28     {
29         if ( !(xudpcb=malloc(sizeof(struct XUDPCB))))
30             xudpError("xudpd: Allocating RAM");
31 
32         printf("[Waiting for client...");
33         fflush(stdout);
34 
35         xudp_getnewuser(xudpcb, xudpscb);
36 
37         printf("accepted client]\n");
38         fflush(stdout);
39 
40         /* FORK BELOW *****************************************************/
41 
42 #ifdef DONTFORK
43 /* DISABLE FORKING */
44         pidChild=0;
45 #endif
46 #ifndef DONTFORK
47         if ((pidChild=fork())<0) xudpError("Trying to fork");
48         else
49 #endif  
50 
51         if (pidChild==0)
52         {
53             /**************************************************************
54              * CONNECT Loop:  Executes until either:
55              *        1) A foreign "xudpd" connects with us through
56              *           the Internet 
57              *        2) Our local user application wishes to place a
58              *           call to a foreign host.
59              */
60             while(!xudpcb->state)
61             {
62                 xudp_handlecontrol(xudpcb, xudpscb);
63             }
64 
65 #ifdef DEBUG
66             show_sockaddr_in(&xudpcb->hostaddr);
67 #endif
68 
69             printf("[Default socket buffer size is 32K]\n");
70             fflush(stdout);
71             xudp_socketinit(xudpcb);
72             
73             xudpcb->state=XUDP_SOFT_START;
74 
75             while(xudpcb->state) /* Main protocol loop *******************/
76             {
77 #ifdef DEBUG
78                 show_status(xudpcb);
79 #endif              
80 #ifdef DELAY
81                 sleep(1);
82 #endif
83                 ts=makeTimestamp();
84                 if (ts-statts>=20)
85                 {
86                     statts=ts;
87 /*                  xudp_windowchange(xudpcb); */
88 #ifdef STATLOG
89                     fprintf(xudpcb->bytlog, "%u %lu\n",
90                              xudpcb->timeElapsed, xudpcb->bytesACKed);
91 /*                  fflush(xudpcb->bytlog);*/
92                     fprintf(xudpcb->rttlog, "%u %u %f\n",
93                             xudpcb->timeElapsed,
94                             xudpcb->rtt, xudpcb->rttavg);
95 /*                  fflush(xudpcb->rttlog);*/
96                     fprintf(xudpcb->paclog, "%u %u\n",
97                             xudpcb->timeElapsed,xudpcb->packetsInPipe);
98 /*                  fflush(xudpcb->paclog);*/
99 #endif
100                 }
101                 xudpcb->timeElapsed=ts;
102 
103                 /** Just poll if the parcel outgoing queue has data */
104                 /** waiting in it AND there's room on the net for it */
105 
106                 if (xudpcb->packetsInPipe<xudpcb->winRemote)
107                     if (xudpcb->pOutHead->next!=NULL)
108                         dontwait=TRUE;
109 
110                 /** Just poll if there's packets waiting to go out */
111 
112                 if (xudpcb->pXmitQueue->next!=NULL) dontwait=TRUE;
113 
114                 pCmd=xudpcb->pCmdQueue->next;
115                 while (pCmd!=NULL)
116                 {
117                     /* Make a command parcel if we're really waiting
118                        around, flushes out commands that might be held in
119                        our queue */
120                     
121                     if ((ts-xudpcb->pCmdQueue->next->timestamp)>=TIMEOUT)
122                     {
123                         xudp_makecommandparcel(xudpcb);
124                         xudpcb->push=TRUE;
125                         pCmd=NULL;
126                     }
127                     
128                     if (pCmd!=NULL) pCmd=pCmd->next;
129                 }
130 
131                 /** Wait a reasonably long time for something on */
132                 /** either the UNIX stream or Internet UDP sockets - */
133                 /** saves system load, unless we're pushing a parcel */
134                 /** or just polling  */
135 
136                 if (!(xudpcb->push) && !(dontwait))
137                 {
138                     result=0;
139                     FD_ZERO(&setFD);
140                     FD_SET(xudpcb->localclient->fdControl, &setFD);
141                     FD_SET(xudpcb->fdCli, &setFD);
142                     timestuff.tv_usec=1000*GRANULARITY*TIMEOUT;
143                     timestuff.tv_sec=0;
144                     if ((result=select(max(xudpcb->localclient->fdControl,
145                                            xudpcb->fdCli)+1, &setFD, NULL,
146                                        NULL, &timestuff))<0) 
147                         xudpError("select"); 
148                 }
149                 else /* PUSH or DONTWAIT is set, do a quick poll */
150                 {
151                     result=0;
152                     FD_ZERO(&setFD);
153                     FD_SET(xudpcb->localclient->fdControl, &setFD);
154                     FD_SET(xudpcb->fdCli, &setFD);
155                     timestuff.tv_usec=0;
156                     timestuff.tv_sec=0;
157                     if ((result=select(max(xudpcb->localclient->fdControl,
158                                            xudpcb->fdCli)+1, &setFD, NULL,
159                                        NULL, &timestuff))<0) 
160                         xudpError("select"); 
161                 }
162                 dontwait=FALSE;
163 
164                 /** See if we're trying to close, if we are, close */
165                 /** after we've waited for everybody. */
166                 
167                 if (xudpcb->state==XUDP_CLOSE_WAIT)
168                     if (makeTimestamp()-(xudpcb->closing)>=TIMECLOSE)
169                         xudpcb->state=0;
170                 if (xudpcb->state)
171                 {
172                     /****** Incoming Commands on UNIX Stream ***********/
173                     if (FD_ISSET(xudpcb->localclient->fdControl, &setFD))
174                         xudp_handlecontrol(xudpcb, xudpscb);
175                     
176                     /****** Incoming packets from the network **********/
177                     /*** Queue on cb->pRecvQueue */
178                     if (FD_ISSET(xudpcb->fdCli, &setFD))
179                         xudp_recv(xudpcb);
180                     
181                     /*** Move packets in cb->pRecvQueue to appropriate */
182                     /*** parcels in cb->pRecvWaitQueue and order them */
183                     xudp_organizeincoming(xudpcb);
184                     
185                     /*** Mark ending packet sequence numbers on parcels */
186                     xudp_endparcel(xudpcb);
187                     
188                     /*** Set the ACK flag on parcels that we've */
189                     /*** received an ACK for */
190                     xudp_recvackparcels(xudpcb);
191 
192                     /*** Set the ACK flag on individual packets that */
193                     /*** we've received an ACK for */ 
194                     xudp_recvackpackets(xudpcb);
195                     
196                     /*** Queue up commands to ACKnowledge parcels that */
197                     /*** we've  received in their entirety */
198                     xudp_ackparcels(xudpcb);
199                     
200                     /*** Queue up commands to ACKnowledge individual */
201                     /*** packets based on various flow control */
202                     /*** algorithms */ 
203                     xudp_ackpackets(xudpcb);
204                     
205                     /*** Reassemble fragmented RAW parcels to */
206                     /*** cb->pInHead formed by completed parcels in */
207                     /*** cb->pRecvWaitQueue */
208                     xudp_reassembleparcel(xudpcb);
209                     
210                     /*** Fragment and queue up packets on */
211                     /*** cb->pXmitQueue to fill up our advertised */
212                     /*** window.  Take packets from queued RAW parcels */
213                     /*** in cb->pOutHead.  Insert waiting commands to */
214                     /*** be sent from cb->pCmdQueue */
215                     xudp_fragmentparcel(xudpcb);
216                     
217                     /*** Send packets queued on cb->pXmitQueue and */
218                     /*** properly queue those packets on the list of */
219                     /*** packets waiting to receive acknowledgements */
220                     /*** (cb->pAckWaitQueue) */ 
221                     xudp_xmit(xudpcb);
222                     
223                     /*** Blow completed RAW parcels on the cb->pInHead */
224                     /*** out to our XUDP application */ 
225                     xudp_dequeueparcel(xudpcb); 
226                     
227                     /*** Remove obsoleted parcels from the queues */
228                     xudp_removeobsolete(xudpcb);
229                     
230                     /*** Retransmit packets that have exceeded their */
231                     /*** RTO's */ 
232                     xudp_retransmit(xudpcb);
233                 }
234             }
235 
236             /** Reset client connections, clean up the mess we've made */
237             /** of RAM and prepare for next client. */ 
238             xudp_loseuser(xudpcb);
239 
240             /** Quit out of this child process */
241             exit(0);
242         } /* end Child Process */
243 
244     } /* end "Loop Forever" */
245 
246     close(xudpscb->fdServ);
247     close(xudpscb->fdServAudio);
248     close(xudpscb->fdServVideo);
249     close(xudpscb->fdServControl);
250     free(xudpscb);
251 }

7.4.2 xudp_init function

int xudp_init(struct XUDPSCB *scb);

 1 int xudp_init(struct XUDPSCB *scb)
 2 {
 3     /* xudpd handles two connection points!
 4        ---------------------------------------
 5        1. It will bind itself to UDP/IP port SERVER_PORT as defined in
 6        xudp.h.  It will accept incoming connections, presumably from
 7        foreign xudpd's.
 8 
 9        2. It will bind itself to UNIX Streams CONTROL_UNIX, AUDIO_UNIX and
10        VIDEO_UNIX as defined in xudp.h.  It will accept incoming connections,
11        presumably from local XUDP applications.*/
12 
13     /* Internet server side ************************************************/
14     
15     if ( (scb->fdServ=socket(AF_INET, SOCK_DGRAM, 0)) <0)
16         xudpError("xudp_init: socket(UDP)");     /* Opens a UDP/IP socket */
17 
18                     /* Fill out address structure for server */
19 
20     scb->addrServ_in.sin_family=AF_INET;         /* AF_INET is the Internet
21                                                     Protocol Family.  */
22     scb->addrServ_in.sin_addr.s_addr=htonl(INADDR_ANY);
23                                                /* Will accept incoming
24                                                   connections from any
25                                                   address */
26 
27     /* Localhost UNIX Protocol server side *****************************/
28 
29     /* makeServer_un creates the UNIX stream sockets, binds them to the
30        specified pathnames and starts listening for connections */
31 
32     scb->fdServAudio=makeServer_un((struct sockaddr_un
33                                     *)&scb->addrServAudio_un, AUDIO_UNIX);
34     scb->fdServVideo=makeServer_un((struct sockaddr_un
35                                     *)&scb->addrServVideo_un, VIDEO_UNIX); 
36     scb->fdServControl=makeServer_un((struct sockaddr_un
37                                       *)&scb->addrServControl_un,
38                                      CONTROL_UNIX);
39     return 0;
40 }

7.4.3 xudp_getnewuser function

int xudp_getnewuser(struct XUDPCB *cb, struct XUDPSCB *scb);

 1 int xudp_getnewuser(struct XUDPCB *cb, struct XUDPSCB *scb)
 2 {
 3     int un_len, i;
 4 
 5     if ( !(cb->localclient=malloc(sizeof(struct XUDPHost))))
 6         xudpError("xudp_getnewuser: Allocating RAM");
 7 
 8     /******* Wait here until a local XUDP application registers with us */
 9 
10     un_len=sizeof(cb->addrControl_un);
11     
12     cb->localclient->fdControl=accept(scb->fdServControl,
13                                       (struct sockaddr *)&cb->addrControl_un,
14                                       &un_len);
15                               /* Block until we accept (or we error
16                                  out) on an incoming UNIX connection.
17                                  The addressing information for the
18                                  client will be stored in addrControl_un */
19     if (cb->localclient->fdControl<0)
20         xudpError("xudpd: Accepting connection (UNIX)"); 
21                               /* Check for errors */
22         
23     un_len=sizeof(cb->addrAudio_un);
24     cb->localclient->fdAudio=accept(scb->fdServAudio,
25                                     (struct sockaddr *)&cb->addrAudio_un,
26                                     &un_len);
27     if (cb->localclient->fdAudio<0)
28         xudpError("xudpd: Accepting connection (UNIX)");
29         
30     un_len=sizeof(cb->addrVideo_un);
31     cb->localclient->fdVideo=accept(scb->fdServVideo,
32                                     (struct sockaddr *)&cb->addrVideo_un,
33                                     &un_len);   
34     if (cb->localclient->fdVideo<0)
35         xudpError("xudpd: Accepting connection (UNIX)");
36 
37     /*** Initialize the variables in the control block for this new */
38     /*** application */
39 
40     cb->pOutHead=makeParcel();
41     cb->pInHead=makeParcel();
42 
43     cb->pAckWaitQueue=makeFragParcel();
44     cb->pRecvWaitQueue=makeFragParcel();
45 
46     cb->pCmdQueue=makeCmd();
47     cb->pCmdInQueue=makeCmd();
48     
49     cb->pXmitQueue=makePacket();
50     cb->pRecvQueue=makePacket();
51 
52     cb->pOutHead->parcel=0;
53     cb->pInHead->parcel=0;
54     cb->pAckWaitQueue->parcel=0;
55     cb->pRecvWaitQueue->parcel=0;
56 
57     cb->mps=MPS;
58     cb->push=0;
59     cb->winAdvertised=MAXWINDOW;
60     cb->winCongestion=1;
61     cb->winRemote=MAXWINDOW;
62     cb->packetsInPipe=0;
63     cb->packetsInPipeRmt=0;
64     cb->rtt=1;
65     cb->rttavg=10.0;
66     cb->rttvar=20.0;
67     cb->rttmax=20.0;
68     cb->rttmin=0.0;
69     cb->rto=20;
70     cb->windowdelta=0.0;
71 
72     for (i=0; i<MAXPARCEL; i++)
73         cb->usedparcels[i]=FALSE;
74 
75 #ifdef SRLOG
76     cb->sendlog=fopen("send.log", "w");
77     cb->recvlog=fopen("recv.log", "w");
78 #endif
79 
80 #ifdef STATLOG
81     cb->bytlog=fopen("stats.byt", "w");
82     cb->rttlog=fopen("stats.rtt", "w");
83     cb->paclog=fopen("stats.pac", "w");
84 #endif
85     return 0;
86 }

7.4.4 xudp_socketinit function

int xudp_socketinit(struct XUDPCB *cb);

 1 int xudp_socketinit(struct XUDPCB *cb)
 2 {
 3     int temp;
 4 
 5     temp=SOCKBUFSIZE;  /* Set up maximum socket-level buffers */
 6     if (setsockopt(cb->localclient->fdControl, SOL_SOCKET, SO_SNDBUF,
 7                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");  
 8     if (setsockopt(cb->localclient->fdControl, SOL_SOCKET, SO_RCVBUF,
 9                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");  
10     if (setsockopt(cb->localclient->fdAudio, SOL_SOCKET, SO_SNDBUF,
11                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");  
12     if (setsockopt(cb->localclient->fdAudio, SOL_SOCKET, SO_RCVBUF,
13                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");  
14     if (setsockopt(cb->localclient->fdVideo, SOL_SOCKET, SO_SNDBUF,
15                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");  
16     if (setsockopt(cb->localclient->fdVideo, SOL_SOCKET, SO_RCVBUF,
17                    &temp, sizeof(int))<0) xudpError("xudp_socketinit");
18     if (setsockopt(cb->fdCli, SOL_SOCKET, SO_SNDBUF, &temp,
19                    sizeof(int))<0) xudpError("xudp_socketinit");  
20     if (setsockopt(cb->fdCli, SOL_SOCKET, SO_RCVBUF, &temp,
21                    sizeof(int))<0) xudpError("xudp_socketinit");  
22 
23     if (fcntl(cb->fdCli, F_SETFL, FNDELAY)<0)
24         xudpError("xudp_socketinit");
25 
26     return 0;
27 }

7.4.5 xudp_loseuser function

int xudp_loseuser(struct XUDPCB *cb);

 1 int xudp_loseuser(struct XUDPCB *cb)
 2 {
 3     xudpSendFunction(cb->localclient, F_CLOSE, NULL);
 4     sleep(1);
 5     close(cb->fdCli);
 6     close(cb->localclient->fdControl);
 7     close(cb->localclient->fdAudio);
 8     close(cb->localclient->fdVideo);
 9     free(cb->localclient);
10 
11     while (cb->pAckWaitQueue->next!=NULL)
12       deleteFragParcel(cb->pAckWaitQueue->next);
13     deleteFragParcel(cb->pAckWaitQueue);
14 
15     while (cb->pOutHead->next!=NULL)
16       deleteParcel(cb->pOutHead->next);
17     deleteParcel(cb->pOutHead);
18 
19     while (cb->pRecvWaitQueue->next!=NULL)
20       deleteFragParcel(cb->pRecvWaitQueue->next);
21     deleteFragParcel(cb->pRecvWaitQueue);
22 
23     while (cb->pInHead->next!=NULL)
24       deleteParcel(cb->pInHead->next);
25     deleteParcel(cb->pInHead);
26 
27     while (cb->pXmitQueue->next!=NULL)
28       deletePacket(cb->pXmitQueue->next);
29     deletePacket(cb->pXmitQueue);
30 
31     while (cb->pRecvQueue->next!=NULL)
32       deletePacket(cb->pRecvQueue->next);
33     deletePacket(cb->pRecvQueue);
34 
35     while (cb->pCmdQueue->next!=NULL)
36       deleteCmd(cb->pCmdQueue->next);
37     deleteCmd(cb->pCmdQueue);
38 
39     while (cb->pCmdInQueue->next!=NULL)
40       deleteCmd(cb->pCmdInQueue->next);
41     deleteCmd(cb->pCmdInQueue);
42 
43 #ifdef SRLOG
44     fclose(cb->sendlog);
45     fclose(cb->recvlog);
46 #endif
47 #ifdef STATLOG
48     fclose(cb->bytlog);
49     fclose(cb->rttlog);
50     fclose(cb->paclog);
51 #endif
52 
53     free(cb);
54     return 0;
55 }

7.4.6 xudp_handlecontrol function

int xudp_handlecontrol(struct XUDPCB *cb, struct XUDPSCB *scb);

 1 int xudp_handlecontrol(struct XUDPCB *cb, struct XUDPSCB *scb)
 2 {
 3     int     fcn=0;
 4     u_short temp;
 5     int     in_len;
 6     char    buffer[25];
 7     struct sockaddr_in remoteaddr, localaddr;
 8     fd_set  setFD;
 9     char    t2;
10     struct XUDPCmd *pCmd;
11 
12     fcn=xudpGetFunction(cb->localclient);
13     switch (fcn)
14     {
15     case F_CONNECT:
16         printf("[Received connection request]\n");
17         fflush(stdout);
18         /* Opens a UDP/IP socket */
19         if ((cb->fdCli=socket(AF_INET, SOCK_DGRAM, 0))<0) 
20             xudpError("xudpd: socket(UDP)");
21         localaddr.sin_family=AF_INET;
22         localaddr.sin_port=htons(0);
23         localaddr.sin_addr.s_addr=htonl(INADDR_ANY);
24         if ((bind(cb->fdCli, (struct sockaddr *)&localaddr,
25              sizeof(struct sockaddr_in)))<0)
26             xudpError("xudpd: bind(UDP)");  /* Sets up a unique port 
27                                                number */ 
28 
29         streamRead(cb->localclient->fdControl, (char *) &cb->hostaddr,
30                    sizeof(struct sockaddr_in));
31         temp=0;
32         while (++temp<5)
33         {
34             if (sendto(cb->fdCli, "HELLO XUDP", 10, 0,
35                        (struct sockaddr *)&cb->hostaddr,
36                        sizeof(struct sockaddr_in))<0)
37                 xudpError("sendto");
38             sleep(1);
39             in_len=sizeof(struct sockaddr_in);
40             if (recvfrom(cb->fdCli, buffer, 10, 0,
41                          (struct sockaddr *)&remoteaddr, &in_len)>0)
42             {
43                 if (memcmp("HELLO XUDP", buffer, 10)==0)
44                 {
45                     temp=101;
46                     /*** Grab the new port number */
47                     memcpy(&cb->hostaddr, &remoteaddr,
48                            sizeof(struct sockaddr_in));
49                     /*** Connect with remote xudpd to gain system
50                       level features */
51                     if (connect(cb->fdCli,
52                                 (struct sockaddr *)&cb->hostaddr,
53                                 sizeof(struct sockaddr_in))<0)
54                         xudpError("connect");
55                 }
56             }
57             else xudpError("recvfrom");
58         }
59         if (temp<100) /* No connect for 5 seconds */
60         {
61             t2=ERR_NOCONNECT;
62             xudpSendFunction(cb->localclient, F_ERROR, (char *)&t2);
63             printf("[Aborted, no connect for 5 seconds]\n");
64             close(cb->fdCli);
65             fflush(stdout);
66         }
67         else
68         {
69             printf("[Connected successfully]\n");
70             fflush(stdout);
71             cb->state=XUDP_ESTABLISHED;
72             xudpSendFunction(cb->localclient, F_CONNECTED,
73                              (char *)&cb->hostaddr); 
74             sleep(1);
75         }
76         break;
77     case F_ACCEPT:
78         printf("[Waiting for foreign clients]\n");
79         fflush(stdout);
80         
81         /*** Wait for foreign xudpd to wake us up */
82         FD_ZERO(&setFD);
83         FD_SET(scb->fdServ, &setFD);
84         
85         /* Wait indefinitely for something on the UDP server socket */
86         while(!cb->state)
87         {
88             temp=0;
89             if (select(scb->fdServ+1, &setFD, NULL, NULL, NULL)<0)
90                 xudpError("select"); 
91             in_len=sizeof(struct sockaddr_in);
92             if (recvfrom(scb->fdServ, buffer, 24, 0, 
93                          (struct sockaddr *)&remoteaddr, &in_len)>0)
94             {
95                 if (memcmp("HELLO XUDP", buffer, 10)==0)
96                 {
97                     /* Opens a UDP/IP socket */
98                     if ((cb->fdCli=socket(AF_INET, SOCK_DGRAM, 0))<0) 
99                         xudpError("xudpd: socket(UDP)");
100                     localaddr.sin_family=AF_INET;
101                     localaddr.sin_port=htons(0);
102                     localaddr.sin_addr.s_addr=htonl(INADDR_ANY);
103                     if (bind(cb->fdCli, (struct sockaddr *)&localaddr,
104                              sizeof(struct sockaddr_in))<0)
105                         xudpError("xudpd: bind");
106                     /* Sets up a unique port number */
107                     memcpy(&cb->hostaddr, &remoteaddr,
108                            sizeof(struct sockaddr_in));
109                     if (sendto(cb->fdCli, "HELLO XUDP", 10, 0,
110                                (struct sockaddr *)&cb->hostaddr,
111                                sizeof(struct sockaddr_in))<0)
112                         xudpError("sendto");
113                     if (connect(cb->fdCli,
114                                 (struct sockaddr *)&cb->hostaddr,
115                                 sizeof(struct sockaddr_in))<0)
116                         xudpError("xudpd: connect");
117                     xudpSendFunction(cb->localclient, F_CONNECTED,
118                                      (char *)&cb->hostaddr); 
119                     cb->state=XUDP_ESTABLISHED;
120                 }
121             }
122         }
123         break;
124     case F_BIND:
125         printf("[Binding local address]\n");
126         fflush(stdout);
127         streamRead(cb->localclient->fdControl, (char *) &temp,
128                    sizeof(u_short)); 
129         if (temp==0) scb->addrServ_in.sin_port=htons(SERVER_PORT);
130         else scb->addrServ_in.sin_port=htons(temp);
131 
132         in_len=sizeof(struct sockaddr_in);
133         
134         if (bind(scb->fdServ, (struct sockaddr *)&(scb->addrServ_in),
135                  in_len)<0 )
136             xudpError("xudpd: bind()");/* We "bind" the server
137                                           to the information
138                                           in xudpserver->Addr */ 
139         break;
140     case F_LISTEN:
141         printf("[Listening for foreign clients]\n");
142         fflush(stdout);
143         listen(scb->fdServ, 1);/* Listen for clients, holding at most 1
144                                   in the queue */ 
145         break;
146     case F_CLOSE:
147         cb->state=XUDP_CLOSE_WAIT;
148         cb->closing=makeTimestamp();
149         pCmd=makeCmd();
150         pCmd->cmd=C_CLOSE;
151         cb->push=TRUE;
152         break;
153     case F_SENDVIDEO:
154         xudp_queueparcel(cb, VIDEO);
155         break;
156     case F_SENDAUDIO:
157         xudp_queueparcel(cb, AUDIO);
158         break;
159     default: break;
160     }
161     return 0;
162 }



Mike Andrews
Wed Mar 19 16:07:58 EST 1997