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