]> git.proxmox.com Git - qemu.git/blobdiff - slirp/socket.c
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
[qemu.git] / slirp / socket.c
index a911b29d901d9ed4a516969365a45dccec44a52d..37ac5cf2fb260cffbf85b5f4f80b72d0fbcc9053 100644 (file)
@@ -41,7 +41,7 @@ solookup(struct socket *head, struct in_addr laddr, u_int lport,
  * insque() it into the correct linked-list
  */
 struct socket *
-socreate(void)
+socreate(Slirp *slirp)
 {
   struct socket *so;
 
@@ -50,6 +50,8 @@ socreate(void)
     memset(so, 0, sizeof(struct socket));
     so->so_state = SS_NOFDREF;
     so->s = -1;
+    so->slirp = slirp;
+    so->pollfds_idx = -1;
   }
   return(so);
 }
@@ -60,15 +62,19 @@ socreate(void)
 void
 sofree(struct socket *so)
 {
+  Slirp *slirp = so->slirp;
+
   if (so->so_emu==EMU_RSH && so->extra) {
        sofree(so->extra);
        so->extra=NULL;
   }
-  if (so == tcp_last_so)
-    tcp_last_so = &tcb;
-  else if (so == udp_last_so)
-    udp_last_so = &udb;
-
+  if (so == slirp->tcp_last_so) {
+      slirp->tcp_last_so = &slirp->tcb;
+  } else if (so == slirp->udp_last_so) {
+      slirp->udp_last_so = &slirp->udb;
+  } else if (so == slirp->icmp_last_so) {
+      slirp->icmp_last_so = &slirp->icmp;
+  }
   m_free(so->so_m);
 
   if(so->so_next && so->so_prev)
@@ -87,8 +93,6 @@ size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np)
        DEBUG_CALL("sopreprbuf");
        DEBUG_ARG("so = %lx", (long )so);
 
-       len = sb->sb_datalen - sb->sb_cc;
-
        if (len <= 0)
                return 0;
 
@@ -163,7 +167,7 @@ soread(struct socket *so)
        nn = readv(so->s, (struct iovec *)iov, n);
        DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
 #else
-       nn = recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
+       nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
 #endif
        if (nn <= 0) {
                if (nn < 0 && (errno == EINTR || errno == EAGAIN))
@@ -188,7 +192,7 @@ soread(struct socket *so)
         */
        if (n == 2 && nn == iov[0].iov_len) {
             int ret;
-            ret = recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
+            ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
             if (ret > 0)
                 nn += ret;
         }
@@ -360,8 +364,6 @@ sowrite(struct socket *so)
         * sowrite wouldn't have been called otherwise
         */
 
-        len = sb->sb_cc;
-
        iov[0].iov_base = sb->sb_rptr;
         iov[1].iov_base = NULL;
         iov[1].iov_len = 0;
@@ -473,7 +475,10 @@ sorecvfrom(struct socket *so)
           int n;
 #endif
 
-         if (!(m = m_get())) return;
+         m = m_get(so->slirp);
+         if (!m) {
+             return;
+         }
          m->m_data += IF_MAXLINKHDR;
 
          /*
@@ -533,6 +538,7 @@ sorecvfrom(struct socket *so)
 int
 sosendto(struct socket *so, struct mbuf *m)
 {
+       Slirp *slirp = so->slirp;
        int ret;
        struct sockaddr_in addr;
 
@@ -541,11 +547,12 @@ sosendto(struct socket *so, struct mbuf *m)
        DEBUG_ARG("m = %lx", (long)m);
 
         addr.sin_family = AF_INET;
-       if ((so->so_faddr.s_addr & vnetwork_mask.s_addr) ==
-           vnetwork_addr.s_addr) {
+       if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+           slirp->vnetwork_addr.s_addr) {
          /* It's an alias */
-         if (so->so_faddr.s_addr == vnameserver_addr.s_addr) {
-           addr.sin_addr = dns_addr;
+         if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
+           if (get_dns_addr(&addr.sin_addr) < 0)
+             addr.sin_addr = loopback_addr;
          } else {
            addr.sin_addr = loopback_addr;
          }
@@ -576,20 +583,24 @@ sosendto(struct socket *so, struct mbuf *m)
  * Listen for incoming TCP connections
  */
 struct socket *
-tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags)
+tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
+           u_int lport, int flags)
 {
        struct sockaddr_in addr;
        struct socket *so;
        int s, opt = 1;
        socklen_t addrlen = sizeof(addr);
+       memset(&addr, 0, addrlen);
 
        DEBUG_CALL("tcp_listen");
-       DEBUG_ARG("port = %d", port);
+       DEBUG_ARG("haddr = %x", haddr);
+       DEBUG_ARG("hport = %d", hport);
        DEBUG_ARG("laddr = %x", laddr);
        DEBUG_ARG("lport = %d", lport);
        DEBUG_ARG("flags = %x", flags);
 
-       if ((so = socreate()) == NULL) {
+       so = socreate(slirp);
+       if (!so) {
          return NULL;
        }
 
@@ -598,7 +609,7 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
                free(so);
                return NULL;
        }
-       insque(so,&tcb);
+       insque(so, &slirp->tcb);
 
        /*
         * SS_FACCEPTONCE sockets must time out.
@@ -615,8 +626,8 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
        addr.sin_addr.s_addr = haddr;
        addr.sin_port = hport;
 
-       if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
-           (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
+       if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+           (socket_set_fast_reuse(s) < 0) ||
            (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
            (listen(s,1) < 0)) {
                int tmperrno = errno; /* Don't clobber the real reason we failed */
@@ -631,12 +642,12 @@ tcp_listen(u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags
 #endif
                return NULL;
        }
-       setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
+       qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
 
        getsockname(s,(struct sockaddr *)&addr,&addrlen);
        so->so_fport = addr.sin_port;
        if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
-          so->so_faddr = vhost_addr;
+          so->so_faddr = slirp->vhost_addr;
        else
           so->so_faddr = addr.sin_addr;
 
@@ -670,9 +681,6 @@ sofcantrcvmore(struct socket *so)
 {
        if ((so->so_state & SS_NOFDREF) == 0) {
                shutdown(so->s,0);
-               if(global_writefds) {
-                 FD_CLR(so->s,global_writefds);
-               }
        }
        so->so_state &= ~(SS_ISFCONNECTING);
        if (so->so_state & SS_FCANTSENDMORE) {
@@ -688,12 +696,6 @@ sofcantsendmore(struct socket *so)
 {
        if ((so->so_state & SS_NOFDREF) == 0) {
             shutdown(so->s,1);           /* send FIN to fhost */
-            if (global_readfds) {
-                FD_CLR(so->s,global_readfds);
-            }
-            if (global_xfds) {
-                FD_CLR(so->s,global_xfds);
-            }
        }
        so->so_state &= ~(SS_ISFCONNECTING);
        if (so->so_state & SS_FCANTRCVMORE) {