Add qemu 2.4.0
[kvmfornfv.git] / qemu / slirp / socket.c
1 /*
2  * Copyright (c) 1995 Danny Gasparovski.
3  *
4  * Please read the file COPYRIGHT for the
5  * terms and conditions of the copyright.
6  */
7
8 #include "qemu-common.h"
9 #include <slirp.h>
10 #include "ip_icmp.h"
11 #ifdef __sun__
12 #include <sys/filio.h>
13 #endif
14
15 static void sofcantrcvmore(struct socket *so);
16 static void sofcantsendmore(struct socket *so);
17
18 struct socket *
19 solookup(struct socket *head, struct in_addr laddr, u_int lport,
20          struct in_addr faddr, u_int fport)
21 {
22         struct socket *so;
23
24         for (so = head->so_next; so != head; so = so->so_next) {
25                 if (so->so_lport == lport &&
26                     so->so_laddr.s_addr == laddr.s_addr &&
27                     so->so_faddr.s_addr == faddr.s_addr &&
28                     so->so_fport == fport)
29                    break;
30         }
31
32         if (so == head)
33            return (struct socket *)NULL;
34         return so;
35
36 }
37
38 /*
39  * Create a new socket, initialise the fields
40  * It is the responsibility of the caller to
41  * insque() it into the correct linked-list
42  */
43 struct socket *
44 socreate(Slirp *slirp)
45 {
46   struct socket *so;
47
48   so = (struct socket *)malloc(sizeof(struct socket));
49   if(so) {
50     memset(so, 0, sizeof(struct socket));
51     so->so_state = SS_NOFDREF;
52     so->s = -1;
53     so->slirp = slirp;
54     so->pollfds_idx = -1;
55   }
56   return(so);
57 }
58
59 /*
60  * remque and free a socket, clobber cache
61  */
62 void
63 sofree(struct socket *so)
64 {
65   Slirp *slirp = so->slirp;
66
67   if (so->so_emu==EMU_RSH && so->extra) {
68         sofree(so->extra);
69         so->extra=NULL;
70   }
71   if (so == slirp->tcp_last_so) {
72       slirp->tcp_last_so = &slirp->tcb;
73   } else if (so == slirp->udp_last_so) {
74       slirp->udp_last_so = &slirp->udb;
75   } else if (so == slirp->icmp_last_so) {
76       slirp->icmp_last_so = &slirp->icmp;
77   }
78   m_free(so->so_m);
79
80   if(so->so_next && so->so_prev)
81     remque(so);  /* crashes if so is not in a queue */
82
83   free(so);
84 }
85
86 size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
87 {
88         int n, lss, total;
89         struct sbuf *sb = &so->so_snd;
90         int len = sb->sb_datalen - sb->sb_cc;
91         int mss = so->so_tcpcb->t_maxseg;
92
93         DEBUG_CALL("sopreprbuf");
94         DEBUG_ARG("so = %lx", (long )so);
95
96         if (len <= 0)
97                 return 0;
98
99         iov[0].iov_base = sb->sb_wptr;
100         iov[1].iov_base = NULL;
101         iov[1].iov_len = 0;
102         if (sb->sb_wptr < sb->sb_rptr) {
103                 iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
104                 /* Should never succeed, but... */
105                 if (iov[0].iov_len > len)
106                    iov[0].iov_len = len;
107                 if (iov[0].iov_len > mss)
108                    iov[0].iov_len -= iov[0].iov_len%mss;
109                 n = 1;
110         } else {
111                 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
112                 /* Should never succeed, but... */
113                 if (iov[0].iov_len > len) iov[0].iov_len = len;
114                 len -= iov[0].iov_len;
115                 if (len) {
116                         iov[1].iov_base = sb->sb_data;
117                         iov[1].iov_len = sb->sb_rptr - sb->sb_data;
118                         if(iov[1].iov_len > len)
119                            iov[1].iov_len = len;
120                         total = iov[0].iov_len + iov[1].iov_len;
121                         if (total > mss) {
122                                 lss = total%mss;
123                                 if (iov[1].iov_len > lss) {
124                                         iov[1].iov_len -= lss;
125                                         n = 2;
126                                 } else {
127                                         lss -= iov[1].iov_len;
128                                         iov[0].iov_len -= lss;
129                                         n = 1;
130                                 }
131                         } else
132                                 n = 2;
133                 } else {
134                         if (iov[0].iov_len > mss)
135                            iov[0].iov_len -= iov[0].iov_len%mss;
136                         n = 1;
137                 }
138         }
139         if (np)
140                 *np = n;
141
142         return iov[0].iov_len + (n - 1) * iov[1].iov_len;
143 }
144
145 /*
146  * Read from so's socket into sb_snd, updating all relevant sbuf fields
147  * NOTE: This will only be called if it is select()ed for reading, so
148  * a read() of 0 (or less) means it's disconnected
149  */
150 int
151 soread(struct socket *so)
152 {
153         int n, nn;
154         struct sbuf *sb = &so->so_snd;
155         struct iovec iov[2];
156
157         DEBUG_CALL("soread");
158         DEBUG_ARG("so = %lx", (long )so);
159
160         /*
161          * No need to check if there's enough room to read.
162          * soread wouldn't have been called if there weren't
163          */
164         sopreprbuf(so, iov, &n);
165
166 #ifdef HAVE_READV
167         nn = readv(so->s, (struct iovec *)iov, n);
168         DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
169 #else
170         nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
171 #endif
172         if (nn <= 0) {
173                 if (nn < 0 && (errno == EINTR || errno == EAGAIN))
174                         return 0;
175                 else {
176                         DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
177                         sofcantrcvmore(so);
178                         tcp_sockclosed(sototcpcb(so));
179                         return -1;
180                 }
181         }
182
183 #ifndef HAVE_READV
184         /*
185          * If there was no error, try and read the second time round
186          * We read again if n = 2 (ie, there's another part of the buffer)
187          * and we read as much as we could in the first read
188          * We don't test for <= 0 this time, because there legitimately
189          * might not be any more data (since the socket is non-blocking),
190          * a close will be detected on next iteration.
191          * A return of -1 wont (shouldn't) happen, since it didn't happen above
192          */
193         if (n == 2 && nn == iov[0].iov_len) {
194             int ret;
195             ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
196             if (ret > 0)
197                 nn += ret;
198         }
199
200         DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
201 #endif
202
203         /* Update fields */
204         sb->sb_cc += nn;
205         sb->sb_wptr += nn;
206         if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
207                 sb->sb_wptr -= sb->sb_datalen;
208         return nn;
209 }
210
211 int soreadbuf(struct socket *so, const char *buf, int size)
212 {
213     int n, nn, copy = size;
214         struct sbuf *sb = &so->so_snd;
215         struct iovec iov[2];
216
217         DEBUG_CALL("soreadbuf");
218         DEBUG_ARG("so = %lx", (long )so);
219
220         /*
221          * No need to check if there's enough room to read.
222          * soread wouldn't have been called if there weren't
223          */
224         if (sopreprbuf(so, iov, &n) < size)
225         goto err;
226
227     nn = MIN(iov[0].iov_len, copy);
228     memcpy(iov[0].iov_base, buf, nn);
229
230     copy -= nn;
231     buf += nn;
232
233     if (copy == 0)
234         goto done;
235
236     memcpy(iov[1].iov_base, buf, copy);
237
238 done:
239     /* Update fields */
240         sb->sb_cc += size;
241         sb->sb_wptr += size;
242         if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
243                 sb->sb_wptr -= sb->sb_datalen;
244     return size;
245 err:
246
247     sofcantrcvmore(so);
248     tcp_sockclosed(sototcpcb(so));
249     fprintf(stderr, "soreadbuf buffer to small");
250     return -1;
251 }
252
253 /*
254  * Get urgent data
255  *
256  * When the socket is created, we set it SO_OOBINLINE,
257  * so when OOB data arrives, we soread() it and everything
258  * in the send buffer is sent as urgent data
259  */
260 void
261 sorecvoob(struct socket *so)
262 {
263         struct tcpcb *tp = sototcpcb(so);
264
265         DEBUG_CALL("sorecvoob");
266         DEBUG_ARG("so = %lx", (long)so);
267
268         /*
269          * We take a guess at how much urgent data has arrived.
270          * In most situations, when urgent data arrives, the next
271          * read() should get all the urgent data.  This guess will
272          * be wrong however if more data arrives just after the
273          * urgent data, or the read() doesn't return all the
274          * urgent data.
275          */
276         soread(so);
277         tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
278         tp->t_force = 1;
279         tcp_output(tp);
280         tp->t_force = 0;
281 }
282
283 /*
284  * Send urgent data
285  * There's a lot duplicated code here, but...
286  */
287 int
288 sosendoob(struct socket *so)
289 {
290         struct sbuf *sb = &so->so_rcv;
291         char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
292
293         int n, len;
294
295         DEBUG_CALL("sosendoob");
296         DEBUG_ARG("so = %lx", (long)so);
297         DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
298
299         if (so->so_urgc > 2048)
300            so->so_urgc = 2048; /* XXXX */
301
302         if (sb->sb_rptr < sb->sb_wptr) {
303                 /* We can send it directly */
304                 n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
305                 so->so_urgc -= n;
306
307                 DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
308         } else {
309                 /*
310                  * Since there's no sendv or sendtov like writev,
311                  * we must copy all data to a linear buffer then
312                  * send it all
313                  */
314                 len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
315                 if (len > so->so_urgc) len = so->so_urgc;
316                 memcpy(buff, sb->sb_rptr, len);
317                 so->so_urgc -= len;
318                 if (so->so_urgc) {
319                         n = sb->sb_wptr - sb->sb_data;
320                         if (n > so->so_urgc) n = so->so_urgc;
321                         memcpy((buff + len), sb->sb_data, n);
322                         so->so_urgc -= n;
323                         len += n;
324                 }
325                 n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
326 #ifdef DEBUG
327                 if (n != len)
328                    DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
329 #endif
330                 DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
331         }
332
333         sb->sb_cc -= n;
334         sb->sb_rptr += n;
335         if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
336                 sb->sb_rptr -= sb->sb_datalen;
337
338         return n;
339 }
340
341 /*
342  * Write data from so_rcv to so's socket,
343  * updating all sbuf field as necessary
344  */
345 int
346 sowrite(struct socket *so)
347 {
348         int  n,nn;
349         struct sbuf *sb = &so->so_rcv;
350         int len = sb->sb_cc;
351         struct iovec iov[2];
352
353         DEBUG_CALL("sowrite");
354         DEBUG_ARG("so = %lx", (long)so);
355
356         if (so->so_urgc) {
357                 sosendoob(so);
358                 if (sb->sb_cc == 0)
359                         return 0;
360         }
361
362         /*
363          * No need to check if there's something to write,
364          * sowrite wouldn't have been called otherwise
365          */
366
367         iov[0].iov_base = sb->sb_rptr;
368         iov[1].iov_base = NULL;
369         iov[1].iov_len = 0;
370         if (sb->sb_rptr < sb->sb_wptr) {
371                 iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
372                 /* Should never succeed, but... */
373                 if (iov[0].iov_len > len) iov[0].iov_len = len;
374                 n = 1;
375         } else {
376                 iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
377                 if (iov[0].iov_len > len) iov[0].iov_len = len;
378                 len -= iov[0].iov_len;
379                 if (len) {
380                         iov[1].iov_base = sb->sb_data;
381                         iov[1].iov_len = sb->sb_wptr - sb->sb_data;
382                         if (iov[1].iov_len > len) iov[1].iov_len = len;
383                         n = 2;
384                 } else
385                         n = 1;
386         }
387         /* Check if there's urgent data to send, and if so, send it */
388
389 #ifdef HAVE_READV
390         nn = writev(so->s, (const struct iovec *)iov, n);
391
392         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
393 #else
394         nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
395 #endif
396         /* This should never happen, but people tell me it does *shrug* */
397         if (nn < 0 && (errno == EAGAIN || errno == EINTR))
398                 return 0;
399
400         if (nn <= 0) {
401                 DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
402                         so->so_state, errno));
403                 sofcantsendmore(so);
404                 tcp_sockclosed(sototcpcb(so));
405                 return -1;
406         }
407
408 #ifndef HAVE_READV
409         if (n == 2 && nn == iov[0].iov_len) {
410             int ret;
411             ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
412             if (ret > 0)
413                 nn += ret;
414         }
415         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
416 #endif
417
418         /* Update sbuf */
419         sb->sb_cc -= nn;
420         sb->sb_rptr += nn;
421         if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
422                 sb->sb_rptr -= sb->sb_datalen;
423
424         /*
425          * If in DRAIN mode, and there's no more data, set
426          * it CANTSENDMORE
427          */
428         if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
429                 sofcantsendmore(so);
430
431         return nn;
432 }
433
434 /*
435  * recvfrom() a UDP socket
436  */
437 void
438 sorecvfrom(struct socket *so)
439 {
440         struct sockaddr_in addr;
441         socklen_t addrlen = sizeof(struct sockaddr_in);
442
443         DEBUG_CALL("sorecvfrom");
444         DEBUG_ARG("so = %lx", (long)so);
445
446         if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
447           char buff[256];
448           int len;
449
450           len = recvfrom(so->s, buff, 256, 0,
451                          (struct sockaddr *)&addr, &addrlen);
452           /* XXX Check if reply is "correct"? */
453
454           if(len == -1 || len == 0) {
455             u_char code=ICMP_UNREACH_PORT;
456
457             if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
458             else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
459
460             DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
461                         errno,strerror(errno)));
462             icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
463           } else {
464             icmp_reflect(so->so_m);
465             so->so_m = NULL; /* Don't m_free() it again! */
466           }
467           /* No need for this socket anymore, udp_detach it */
468           udp_detach(so);
469         } else {                                /* A "normal" UDP packet */
470           struct mbuf *m;
471           int len;
472 #ifdef _WIN32
473           unsigned long n;
474 #else
475           int n;
476 #endif
477
478           m = m_get(so->slirp);
479           if (!m) {
480               return;
481           }
482           m->m_data += IF_MAXLINKHDR;
483
484           /*
485            * XXX Shouldn't FIONREAD packets destined for port 53,
486            * but I don't know the max packet size for DNS lookups
487            */
488           len = M_FREEROOM(m);
489           /* if (so->so_fport != htons(53)) { */
490           ioctlsocket(so->s, FIONREAD, &n);
491
492           if (n > len) {
493             n = (m->m_data - m->m_dat) + m->m_len + n + 1;
494             m_inc(m, n);
495             len = M_FREEROOM(m);
496           }
497           /* } */
498
499           m->m_len = recvfrom(so->s, m->m_data, len, 0,
500                               (struct sockaddr *)&addr, &addrlen);
501           DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
502                       m->m_len, errno,strerror(errno)));
503           if(m->m_len<0) {
504             u_char code=ICMP_UNREACH_PORT;
505
506             if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
507             else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
508
509             DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
510             icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
511             m_free(m);
512           } else {
513           /*
514            * Hack: domain name lookup will be used the most for UDP,
515            * and since they'll only be used once there's no need
516            * for the 4 minute (or whatever) timeout... So we time them
517            * out much quicker (10 seconds  for now...)
518            */
519             if (so->so_expire) {
520               if (so->so_fport == htons(53))
521                 so->so_expire = curtime + SO_EXPIREFAST;
522               else
523                 so->so_expire = curtime + SO_EXPIRE;
524             }
525
526             /*
527              * If this packet was destined for CTL_ADDR,
528              * make it look like that's where it came from, done by udp_output
529              */
530             udp_output(so, m, &addr);
531           } /* rx error */
532         } /* if ping packet */
533 }
534
535 /*
536  * sendto() a socket
537  */
538 int
539 sosendto(struct socket *so, struct mbuf *m)
540 {
541         Slirp *slirp = so->slirp;
542         int ret;
543         struct sockaddr_in addr;
544
545         DEBUG_CALL("sosendto");
546         DEBUG_ARG("so = %lx", (long)so);
547         DEBUG_ARG("m = %lx", (long)m);
548
549         addr.sin_family = AF_INET;
550         if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
551             slirp->vnetwork_addr.s_addr) {
552           /* It's an alias */
553           if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
554             if (get_dns_addr(&addr.sin_addr) < 0)
555               addr.sin_addr = loopback_addr;
556           } else {
557             addr.sin_addr = loopback_addr;
558           }
559         } else
560           addr.sin_addr = so->so_faddr;
561         addr.sin_port = so->so_fport;
562
563         DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
564
565         /* Don't care what port we get */
566         ret = sendto(so->s, m->m_data, m->m_len, 0,
567                      (struct sockaddr *)&addr, sizeof (struct sockaddr));
568         if (ret < 0)
569                 return -1;
570
571         /*
572          * Kill the socket if there's no reply in 4 minutes,
573          * but only if it's an expirable socket
574          */
575         if (so->so_expire)
576                 so->so_expire = curtime + SO_EXPIRE;
577         so->so_state &= SS_PERSISTENT_MASK;
578         so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
579         return 0;
580 }
581
582 /*
583  * Listen for incoming TCP connections
584  */
585 struct socket *
586 tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
587            u_int lport, int flags)
588 {
589         struct sockaddr_in addr;
590         struct socket *so;
591         int s, opt = 1;
592         socklen_t addrlen = sizeof(addr);
593         memset(&addr, 0, addrlen);
594
595         DEBUG_CALL("tcp_listen");
596         DEBUG_ARG("haddr = %x", haddr);
597         DEBUG_ARG("hport = %d", hport);
598         DEBUG_ARG("laddr = %x", laddr);
599         DEBUG_ARG("lport = %d", lport);
600         DEBUG_ARG("flags = %x", flags);
601
602         so = socreate(slirp);
603         if (!so) {
604           return NULL;
605         }
606
607         /* Don't tcp_attach... we don't need so_snd nor so_rcv */
608         if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) {
609                 free(so);
610                 return NULL;
611         }
612         insque(so, &slirp->tcb);
613
614         /*
615          * SS_FACCEPTONCE sockets must time out.
616          */
617         if (flags & SS_FACCEPTONCE)
618            so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
619
620         so->so_state &= SS_PERSISTENT_MASK;
621         so->so_state |= (SS_FACCEPTCONN | flags);
622         so->so_lport = lport; /* Kept in network format */
623         so->so_laddr.s_addr = laddr; /* Ditto */
624
625         addr.sin_family = AF_INET;
626         addr.sin_addr.s_addr = haddr;
627         addr.sin_port = hport;
628
629         if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
630             (socket_set_fast_reuse(s) < 0) ||
631             (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
632             (listen(s,1) < 0)) {
633                 int tmperrno = errno; /* Don't clobber the real reason we failed */
634
635                 close(s);
636                 sofree(so);
637                 /* Restore the real errno */
638 #ifdef _WIN32
639                 WSASetLastError(tmperrno);
640 #else
641                 errno = tmperrno;
642 #endif
643                 return NULL;
644         }
645         qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
646
647         getsockname(s,(struct sockaddr *)&addr,&addrlen);
648         so->so_fport = addr.sin_port;
649         if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
650            so->so_faddr = slirp->vhost_addr;
651         else
652            so->so_faddr = addr.sin_addr;
653
654         so->s = s;
655         return so;
656 }
657
658 /*
659  * Various session state calls
660  * XXX Should be #define's
661  * The socket state stuff needs work, these often get call 2 or 3
662  * times each when only 1 was needed
663  */
664 void
665 soisfconnecting(struct socket *so)
666 {
667         so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
668                           SS_FCANTSENDMORE|SS_FWDRAIN);
669         so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
670 }
671
672 void
673 soisfconnected(struct socket *so)
674 {
675         so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
676         so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
677 }
678
679 static void
680 sofcantrcvmore(struct socket *so)
681 {
682         if ((so->so_state & SS_NOFDREF) == 0) {
683                 shutdown(so->s,0);
684         }
685         so->so_state &= ~(SS_ISFCONNECTING);
686         if (so->so_state & SS_FCANTSENDMORE) {
687            so->so_state &= SS_PERSISTENT_MASK;
688            so->so_state |= SS_NOFDREF; /* Don't select it */
689         } else {
690            so->so_state |= SS_FCANTRCVMORE;
691         }
692 }
693
694 static void
695 sofcantsendmore(struct socket *so)
696 {
697         if ((so->so_state & SS_NOFDREF) == 0) {
698             shutdown(so->s,1);           /* send FIN to fhost */
699         }
700         so->so_state &= ~(SS_ISFCONNECTING);
701         if (so->so_state & SS_FCANTRCVMORE) {
702            so->so_state &= SS_PERSISTENT_MASK;
703            so->so_state |= SS_NOFDREF; /* as above */
704         } else {
705            so->so_state |= SS_FCANTSENDMORE;
706         }
707 }
708
709 /*
710  * Set write drain mode
711  * Set CANTSENDMORE once all data has been write()n
712  */
713 void
714 sofwdrain(struct socket *so)
715 {
716         if (so->so_rcv.sb_cc)
717                 so->so_state |= SS_FWDRAIN;
718         else
719                 sofcantsendmore(so);
720 }