File:  [Qemu by Fabrice Bellard] / qemu / slirp / socket.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:41:04 2018 UTC (2 years, 10 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0125, qemu0124, qemu0123, qemu0122, qemu0121, qemu0120, HEAD
qemu 0.12.0

    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:   }
   55:   return(so);
   56: }
   57: 
   58: /*
   59:  * remque and free a socket, clobber cache
   60:  */
   61: void
   62: sofree(struct socket *so)
   63: {
   64:   Slirp *slirp = so->slirp;
   65: 
   66:   if (so->so_emu==EMU_RSH && so->extra) {
   67: 	sofree(so->extra);
   68: 	so->extra=NULL;
   69:   }
   70:   if (so == slirp->tcp_last_so) {
   71:       slirp->tcp_last_so = &slirp->tcb;
   72:   } else if (so == slirp->udp_last_so) {
   73:       slirp->udp_last_so = &slirp->udb;
   74:   }
   75:   m_free(so->so_m);
   76: 
   77:   if(so->so_next && so->so_prev)
   78:     remque(so);  /* crashes if so is not in a queue */
   79: 
   80:   free(so);
   81: }
   82: 
   83: size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
   84: {
   85: 	int n, lss, total;
   86: 	struct sbuf *sb = &so->so_snd;
   87: 	int len = sb->sb_datalen - sb->sb_cc;
   88: 	int mss = so->so_tcpcb->t_maxseg;
   89: 
   90: 	DEBUG_CALL("sopreprbuf");
   91: 	DEBUG_ARG("so = %lx", (long )so);
   92: 
   93: 	len = sb->sb_datalen - sb->sb_cc;
   94: 
   95: 	if (len <= 0)
   96: 		return 0;
   97: 
   98: 	iov[0].iov_base = sb->sb_wptr;
   99:         iov[1].iov_base = NULL;
  100:         iov[1].iov_len = 0;
  101: 	if (sb->sb_wptr < sb->sb_rptr) {
  102: 		iov[0].iov_len = sb->sb_rptr - sb->sb_wptr;
  103: 		/* Should never succeed, but... */
  104: 		if (iov[0].iov_len > len)
  105: 		   iov[0].iov_len = len;
  106: 		if (iov[0].iov_len > mss)
  107: 		   iov[0].iov_len -= iov[0].iov_len%mss;
  108: 		n = 1;
  109: 	} else {
  110: 		iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_wptr;
  111: 		/* Should never succeed, but... */
  112: 		if (iov[0].iov_len > len) iov[0].iov_len = len;
  113: 		len -= iov[0].iov_len;
  114: 		if (len) {
  115: 			iov[1].iov_base = sb->sb_data;
  116: 			iov[1].iov_len = sb->sb_rptr - sb->sb_data;
  117: 			if(iov[1].iov_len > len)
  118: 			   iov[1].iov_len = len;
  119: 			total = iov[0].iov_len + iov[1].iov_len;
  120: 			if (total > mss) {
  121: 				lss = total%mss;
  122: 				if (iov[1].iov_len > lss) {
  123: 					iov[1].iov_len -= lss;
  124: 					n = 2;
  125: 				} else {
  126: 					lss -= iov[1].iov_len;
  127: 					iov[0].iov_len -= lss;
  128: 					n = 1;
  129: 				}
  130: 			} else
  131: 				n = 2;
  132: 		} else {
  133: 			if (iov[0].iov_len > mss)
  134: 			   iov[0].iov_len -= iov[0].iov_len%mss;
  135: 			n = 1;
  136: 		}
  137: 	}
  138: 	if (np)
  139: 		*np = n;
  140: 
  141: 	return iov[0].iov_len + (n - 1) * iov[1].iov_len;
  142: }
  143: 
  144: /*
  145:  * Read from so's socket into sb_snd, updating all relevant sbuf fields
  146:  * NOTE: This will only be called if it is select()ed for reading, so
  147:  * a read() of 0 (or less) means it's disconnected
  148:  */
  149: int
  150: soread(struct socket *so)
  151: {
  152: 	int n, nn;
  153: 	struct sbuf *sb = &so->so_snd;
  154: 	struct iovec iov[2];
  155: 
  156: 	DEBUG_CALL("soread");
  157: 	DEBUG_ARG("so = %lx", (long )so);
  158: 
  159: 	/*
  160: 	 * No need to check if there's enough room to read.
  161: 	 * soread wouldn't have been called if there weren't
  162: 	 */
  163: 	sopreprbuf(so, iov, &n);
  164: 
  165: #ifdef HAVE_READV
  166: 	nn = readv(so->s, (struct iovec *)iov, n);
  167: 	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
  168: #else
  169: 	nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
  170: #endif
  171: 	if (nn <= 0) {
  172: 		if (nn < 0 && (errno == EINTR || errno == EAGAIN))
  173: 			return 0;
  174: 		else {
  175: 			DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
  176: 			sofcantrcvmore(so);
  177: 			tcp_sockclosed(sototcpcb(so));
  178: 			return -1;
  179: 		}
  180: 	}
  181: 
  182: #ifndef HAVE_READV
  183: 	/*
  184: 	 * If there was no error, try and read the second time round
  185: 	 * We read again if n = 2 (ie, there's another part of the buffer)
  186: 	 * and we read as much as we could in the first read
  187: 	 * We don't test for <= 0 this time, because there legitimately
  188: 	 * might not be any more data (since the socket is non-blocking),
  189: 	 * a close will be detected on next iteration.
  190: 	 * A return of -1 wont (shouldn't) happen, since it didn't happen above
  191: 	 */
  192: 	if (n == 2 && nn == iov[0].iov_len) {
  193:             int ret;
  194:             ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
  195:             if (ret > 0)
  196:                 nn += ret;
  197:         }
  198: 
  199: 	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
  200: #endif
  201: 
  202: 	/* Update fields */
  203: 	sb->sb_cc += nn;
  204: 	sb->sb_wptr += nn;
  205: 	if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
  206: 		sb->sb_wptr -= sb->sb_datalen;
  207: 	return nn;
  208: }
  209: 
  210: int soreadbuf(struct socket *so, const char *buf, int size)
  211: {
  212:     int n, nn, copy = size;
  213: 	struct sbuf *sb = &so->so_snd;
  214: 	struct iovec iov[2];
  215: 
  216: 	DEBUG_CALL("soreadbuf");
  217: 	DEBUG_ARG("so = %lx", (long )so);
  218: 
  219: 	/*
  220: 	 * No need to check if there's enough room to read.
  221: 	 * soread wouldn't have been called if there weren't
  222: 	 */
  223: 	if (sopreprbuf(so, iov, &n) < size)
  224:         goto err;
  225: 
  226:     nn = MIN(iov[0].iov_len, copy);
  227:     memcpy(iov[0].iov_base, buf, nn);
  228: 
  229:     copy -= nn;
  230:     buf += nn;
  231: 
  232:     if (copy == 0)
  233:         goto done;
  234: 
  235:     memcpy(iov[1].iov_base, buf, copy);
  236: 
  237: done:
  238:     /* Update fields */
  239: 	sb->sb_cc += size;
  240: 	sb->sb_wptr += size;
  241: 	if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
  242: 		sb->sb_wptr -= sb->sb_datalen;
  243:     return size;
  244: err:
  245: 
  246:     sofcantrcvmore(so);
  247:     tcp_sockclosed(sototcpcb(so));
  248:     fprintf(stderr, "soreadbuf buffer to small");
  249:     return -1;
  250: }
  251: 
  252: /*
  253:  * Get urgent data
  254:  *
  255:  * When the socket is created, we set it SO_OOBINLINE,
  256:  * so when OOB data arrives, we soread() it and everything
  257:  * in the send buffer is sent as urgent data
  258:  */
  259: void
  260: sorecvoob(struct socket *so)
  261: {
  262: 	struct tcpcb *tp = sototcpcb(so);
  263: 
  264: 	DEBUG_CALL("sorecvoob");
  265: 	DEBUG_ARG("so = %lx", (long)so);
  266: 
  267: 	/*
  268: 	 * We take a guess at how much urgent data has arrived.
  269: 	 * In most situations, when urgent data arrives, the next
  270: 	 * read() should get all the urgent data.  This guess will
  271: 	 * be wrong however if more data arrives just after the
  272: 	 * urgent data, or the read() doesn't return all the
  273: 	 * urgent data.
  274: 	 */
  275: 	soread(so);
  276: 	tp->snd_up = tp->snd_una + so->so_snd.sb_cc;
  277: 	tp->t_force = 1;
  278: 	tcp_output(tp);
  279: 	tp->t_force = 0;
  280: }
  281: 
  282: /*
  283:  * Send urgent data
  284:  * There's a lot duplicated code here, but...
  285:  */
  286: int
  287: sosendoob(struct socket *so)
  288: {
  289: 	struct sbuf *sb = &so->so_rcv;
  290: 	char buff[2048]; /* XXX Shouldn't be sending more oob data than this */
  291: 
  292: 	int n, len;
  293: 
  294: 	DEBUG_CALL("sosendoob");
  295: 	DEBUG_ARG("so = %lx", (long)so);
  296: 	DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);
  297: 
  298: 	if (so->so_urgc > 2048)
  299: 	   so->so_urgc = 2048; /* XXXX */
  300: 
  301: 	if (sb->sb_rptr < sb->sb_wptr) {
  302: 		/* We can send it directly */
  303: 		n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */
  304: 		so->so_urgc -= n;
  305: 
  306: 		DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
  307: 	} else {
  308: 		/*
  309: 		 * Since there's no sendv or sendtov like writev,
  310: 		 * we must copy all data to a linear buffer then
  311: 		 * send it all
  312: 		 */
  313: 		len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
  314: 		if (len > so->so_urgc) len = so->so_urgc;
  315: 		memcpy(buff, sb->sb_rptr, len);
  316: 		so->so_urgc -= len;
  317: 		if (so->so_urgc) {
  318: 			n = sb->sb_wptr - sb->sb_data;
  319: 			if (n > so->so_urgc) n = so->so_urgc;
  320: 			memcpy((buff + len), sb->sb_data, n);
  321: 			so->so_urgc -= n;
  322: 			len += n;
  323: 		}
  324: 		n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */
  325: #ifdef DEBUG
  326: 		if (n != len)
  327: 		   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));
  328: #endif
  329: 		DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));
  330: 	}
  331: 
  332: 	sb->sb_cc -= n;
  333: 	sb->sb_rptr += n;
  334: 	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
  335: 		sb->sb_rptr -= sb->sb_datalen;
  336: 
  337: 	return n;
  338: }
  339: 
  340: /*
  341:  * Write data from so_rcv to so's socket,
  342:  * updating all sbuf field as necessary
  343:  */
  344: int
  345: sowrite(struct socket *so)
  346: {
  347: 	int  n,nn;
  348: 	struct sbuf *sb = &so->so_rcv;
  349: 	int len = sb->sb_cc;
  350: 	struct iovec iov[2];
  351: 
  352: 	DEBUG_CALL("sowrite");
  353: 	DEBUG_ARG("so = %lx", (long)so);
  354: 
  355: 	if (so->so_urgc) {
  356: 		sosendoob(so);
  357: 		if (sb->sb_cc == 0)
  358: 			return 0;
  359: 	}
  360: 
  361: 	/*
  362: 	 * No need to check if there's something to write,
  363: 	 * sowrite wouldn't have been called otherwise
  364: 	 */
  365: 
  366:         len = sb->sb_cc;
  367: 
  368: 	iov[0].iov_base = sb->sb_rptr;
  369:         iov[1].iov_base = NULL;
  370:         iov[1].iov_len = 0;
  371: 	if (sb->sb_rptr < sb->sb_wptr) {
  372: 		iov[0].iov_len = sb->sb_wptr - sb->sb_rptr;
  373: 		/* Should never succeed, but... */
  374: 		if (iov[0].iov_len > len) iov[0].iov_len = len;
  375: 		n = 1;
  376: 	} else {
  377: 		iov[0].iov_len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;
  378: 		if (iov[0].iov_len > len) iov[0].iov_len = len;
  379: 		len -= iov[0].iov_len;
  380: 		if (len) {
  381: 			iov[1].iov_base = sb->sb_data;
  382: 			iov[1].iov_len = sb->sb_wptr - sb->sb_data;
  383: 			if (iov[1].iov_len > len) iov[1].iov_len = len;
  384: 			n = 2;
  385: 		} else
  386: 			n = 1;
  387: 	}
  388: 	/* Check if there's urgent data to send, and if so, send it */
  389: 
  390: #ifdef HAVE_READV
  391: 	nn = writev(so->s, (const struct iovec *)iov, n);
  392: 
  393: 	DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
  394: #else
  395: 	nn = slirp_send(so, iov[0].iov_base, iov[0].iov_len,0);
  396: #endif
  397: 	/* This should never happen, but people tell me it does *shrug* */
  398: 	if (nn < 0 && (errno == EAGAIN || errno == EINTR))
  399: 		return 0;
  400: 
  401: 	if (nn <= 0) {
  402: 		DEBUG_MISC((dfd, " --- sowrite disconnected, so->so_state = %x, errno = %d\n",
  403: 			so->so_state, errno));
  404: 		sofcantsendmore(so);
  405: 		tcp_sockclosed(sototcpcb(so));
  406: 		return -1;
  407: 	}
  408: 
  409: #ifndef HAVE_READV
  410: 	if (n == 2 && nn == iov[0].iov_len) {
  411:             int ret;
  412:             ret = slirp_send(so, iov[1].iov_base, iov[1].iov_len,0);
  413:             if (ret > 0)
  414:                 nn += ret;
  415:         }
  416:         DEBUG_MISC((dfd, "  ... wrote nn = %d bytes\n", nn));
  417: #endif
  418: 
  419: 	/* Update sbuf */
  420: 	sb->sb_cc -= nn;
  421: 	sb->sb_rptr += nn;
  422: 	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))
  423: 		sb->sb_rptr -= sb->sb_datalen;
  424: 
  425: 	/*
  426: 	 * If in DRAIN mode, and there's no more data, set
  427: 	 * it CANTSENDMORE
  428: 	 */
  429: 	if ((so->so_state & SS_FWDRAIN) && sb->sb_cc == 0)
  430: 		sofcantsendmore(so);
  431: 
  432: 	return nn;
  433: }
  434: 
  435: /*
  436:  * recvfrom() a UDP socket
  437:  */
  438: void
  439: sorecvfrom(struct socket *so)
  440: {
  441: 	struct sockaddr_in addr;
  442: 	socklen_t addrlen = sizeof(struct sockaddr_in);
  443: 
  444: 	DEBUG_CALL("sorecvfrom");
  445: 	DEBUG_ARG("so = %lx", (long)so);
  446: 
  447: 	if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
  448: 	  char buff[256];
  449: 	  int len;
  450: 
  451: 	  len = recvfrom(so->s, buff, 256, 0,
  452: 			 (struct sockaddr *)&addr, &addrlen);
  453: 	  /* XXX Check if reply is "correct"? */
  454: 
  455: 	  if(len == -1 || len == 0) {
  456: 	    u_char code=ICMP_UNREACH_PORT;
  457: 
  458: 	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
  459: 	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
  460: 
  461: 	    DEBUG_MISC((dfd," udp icmp rx errno = %d-%s\n",
  462: 			errno,strerror(errno)));
  463: 	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
  464: 	  } else {
  465: 	    icmp_reflect(so->so_m);
  466:             so->so_m = NULL; /* Don't m_free() it again! */
  467: 	  }
  468: 	  /* No need for this socket anymore, udp_detach it */
  469: 	  udp_detach(so);
  470: 	} else {                            	/* A "normal" UDP packet */
  471: 	  struct mbuf *m;
  472:           int len;
  473: #ifdef _WIN32
  474:           unsigned long n;
  475: #else
  476:           int n;
  477: #endif
  478: 
  479: 	  m = m_get(so->slirp);
  480: 	  if (!m) {
  481: 	      return;
  482: 	  }
  483: 	  m->m_data += IF_MAXLINKHDR;
  484: 
  485: 	  /*
  486: 	   * XXX Shouldn't FIONREAD packets destined for port 53,
  487: 	   * but I don't know the max packet size for DNS lookups
  488: 	   */
  489: 	  len = M_FREEROOM(m);
  490: 	  /* if (so->so_fport != htons(53)) { */
  491: 	  ioctlsocket(so->s, FIONREAD, &n);
  492: 
  493: 	  if (n > len) {
  494: 	    n = (m->m_data - m->m_dat) + m->m_len + n + 1;
  495: 	    m_inc(m, n);
  496: 	    len = M_FREEROOM(m);
  497: 	  }
  498: 	  /* } */
  499: 
  500: 	  m->m_len = recvfrom(so->s, m->m_data, len, 0,
  501: 			      (struct sockaddr *)&addr, &addrlen);
  502: 	  DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
  503: 		      m->m_len, errno,strerror(errno)));
  504: 	  if(m->m_len<0) {
  505: 	    u_char code=ICMP_UNREACH_PORT;
  506: 
  507: 	    if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
  508: 	    else if(errno == ENETUNREACH) code=ICMP_UNREACH_NET;
  509: 
  510: 	    DEBUG_MISC((dfd," rx error, tx icmp ICMP_UNREACH:%i\n", code));
  511: 	    icmp_error(so->so_m, ICMP_UNREACH,code, 0,strerror(errno));
  512: 	    m_free(m);
  513: 	  } else {
  514: 	  /*
  515: 	   * Hack: domain name lookup will be used the most for UDP,
  516: 	   * and since they'll only be used once there's no need
  517: 	   * for the 4 minute (or whatever) timeout... So we time them
  518: 	   * out much quicker (10 seconds  for now...)
  519: 	   */
  520: 	    if (so->so_expire) {
  521: 	      if (so->so_fport == htons(53))
  522: 		so->so_expire = curtime + SO_EXPIREFAST;
  523: 	      else
  524: 		so->so_expire = curtime + SO_EXPIRE;
  525: 	    }
  526: 
  527: 	    /*
  528: 	     * If this packet was destined for CTL_ADDR,
  529: 	     * make it look like that's where it came from, done by udp_output
  530: 	     */
  531: 	    udp_output(so, m, &addr);
  532: 	  } /* rx error */
  533: 	} /* if ping packet */
  534: }
  535: 
  536: /*
  537:  * sendto() a socket
  538:  */
  539: int
  540: sosendto(struct socket *so, struct mbuf *m)
  541: {
  542: 	Slirp *slirp = so->slirp;
  543: 	int ret;
  544: 	struct sockaddr_in addr;
  545: 
  546: 	DEBUG_CALL("sosendto");
  547: 	DEBUG_ARG("so = %lx", (long)so);
  548: 	DEBUG_ARG("m = %lx", (long)m);
  549: 
  550:         addr.sin_family = AF_INET;
  551: 	if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
  552: 	    slirp->vnetwork_addr.s_addr) {
  553: 	  /* It's an alias */
  554: 	  if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
  555: 	    if (get_dns_addr(&addr.sin_addr) < 0)
  556: 	      addr.sin_addr = loopback_addr;
  557: 	  } else {
  558: 	    addr.sin_addr = loopback_addr;
  559: 	  }
  560: 	} else
  561: 	  addr.sin_addr = so->so_faddr;
  562: 	addr.sin_port = so->so_fport;
  563: 
  564: 	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)));
  565: 
  566: 	/* Don't care what port we get */
  567: 	ret = sendto(so->s, m->m_data, m->m_len, 0,
  568: 		     (struct sockaddr *)&addr, sizeof (struct sockaddr));
  569: 	if (ret < 0)
  570: 		return -1;
  571: 
  572: 	/*
  573: 	 * Kill the socket if there's no reply in 4 minutes,
  574: 	 * but only if it's an expirable socket
  575: 	 */
  576: 	if (so->so_expire)
  577: 		so->so_expire = curtime + SO_EXPIRE;
  578: 	so->so_state &= SS_PERSISTENT_MASK;
  579: 	so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
  580: 	return 0;
  581: }
  582: 
  583: /*
  584:  * Listen for incoming TCP connections
  585:  */
  586: struct socket *
  587: tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,
  588:            u_int lport, int flags)
  589: {
  590: 	struct sockaddr_in addr;
  591: 	struct socket *so;
  592: 	int s, opt = 1;
  593: 	socklen_t addrlen = sizeof(addr);
  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: 	    (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 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: 	setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&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: 		if(global_writefds) {
  685: 		  FD_CLR(so->s,global_writefds);
  686: 		}
  687: 	}
  688: 	so->so_state &= ~(SS_ISFCONNECTING);
  689: 	if (so->so_state & SS_FCANTSENDMORE) {
  690: 	   so->so_state &= SS_PERSISTENT_MASK;
  691: 	   so->so_state |= SS_NOFDREF; /* Don't select it */
  692: 	} else {
  693: 	   so->so_state |= SS_FCANTRCVMORE;
  694: 	}
  695: }
  696: 
  697: static void
  698: sofcantsendmore(struct socket *so)
  699: {
  700: 	if ((so->so_state & SS_NOFDREF) == 0) {
  701:             shutdown(so->s,1);           /* send FIN to fhost */
  702:             if (global_readfds) {
  703:                 FD_CLR(so->s,global_readfds);
  704:             }
  705:             if (global_xfds) {
  706:                 FD_CLR(so->s,global_xfds);
  707:             }
  708: 	}
  709: 	so->so_state &= ~(SS_ISFCONNECTING);
  710: 	if (so->so_state & SS_FCANTRCVMORE) {
  711: 	   so->so_state &= SS_PERSISTENT_MASK;
  712: 	   so->so_state |= SS_NOFDREF; /* as above */
  713: 	} else {
  714: 	   so->so_state |= SS_FCANTSENDMORE;
  715: 	}
  716: }
  717: 
  718: /*
  719:  * Set write drain mode
  720:  * Set CANTSENDMORE once all data has been write()n
  721:  */
  722: void
  723: sofwdrain(struct socket *so)
  724: {
  725: 	if (so->so_rcv.sb_cc)
  726: 		so->so_state |= SS_FWDRAIN;
  727: 	else
  728: 		sofcantsendmore(so);
  729: }

unix.superglobalmegacorp.com