static void sofcantrcvmore(struct socket *so);
static void sofcantsendmore(struct socket *so);
-#if 0
-static void
-so_init()
-{
- /* Nothing yet */
-}
-#endif
-
struct socket *
solookup(struct socket *head, struct in_addr laddr, u_int lport,
struct in_addr faddr, u_int fport)
* insque() it into the correct linked-list
*/
struct socket *
-socreate(void)
+socreate(Slirp *slirp)
{
struct socket *so;
memset(so, 0, sizeof(struct socket));
so->so_state = SS_NOFDREF;
so->s = -1;
+ so->slirp = slirp;
}
return(so);
}
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)
DEBUG_CALL("sopreprbuf");
DEBUG_ARG("so = %lx", (long )so);
- len = sb->sb_datalen - sb->sb_cc;
-
if (len <= 0)
return 0;
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))
*/
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;
}
* 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;
int n;
#endif
- if (!(m = m_get())) return;
+ m = m_get(so->slirp);
+ if (!m) {
+ return;
+ }
m->m_data += IF_MAXLINKHDR;
/*
so->so_expire = curtime + SO_EXPIRE;
}
- /* if (m->m_len == len) {
- * m_inc(m, MINCSIZE);
- * m->m_len = 0;
- * }
- */
-
/*
* If this packet was destined for CTL_ADDR,
* make it look like that's where it came from, done by udp_output
int
sosendto(struct socket *so, struct mbuf *m)
{
+ Slirp *slirp = so->slirp;
int ret;
struct sockaddr_in addr;
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;
}
*/
if (so->so_expire)
so->so_expire = curtime + SO_EXPIRE;
- so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
+ so->so_state &= SS_PERSISTENT_MASK;
+ so->so_state |= SS_ISFCONNECTED; /* So that it gets select()ed */
return 0;
}
* 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) {
- /* free(so); Not sofree() ??? free(NULL) == NOP */
+ so = socreate(slirp);
+ if (!so) {
return NULL;
}
free(so);
return NULL;
}
- insque(so,&tcb);
+ insque(so, &slirp->tcb);
/*
* SS_FACCEPTONCE sockets must time out.
if (flags & SS_FACCEPTONCE)
so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2;
- so->so_state = (SS_FACCEPTCONN|flags);
+ so->so_state &= SS_PERSISTENT_MASK;
+ so->so_state |= (SS_FACCEPTCONN | flags);
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
addr.sin_addr.s_addr = haddr;
addr.sin_port = hport;
- if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+ if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
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;
return so;
}
-#if 0
-/*
- * Data is available in so_rcv
- * Just write() the data to the socket
- * XXX not yet...
- */
-static void
-sorwakeup(so)
- struct socket *so;
-{
-/* sowrite(so); */
-/* FD_CLR(so->s,&writefds); */
-}
-
-/*
- * Data has been freed in so_snd
- * We have room for a read() if we want to
- * For now, don't read, it'll be done in the main loop
- */
-static void
-sowwakeup(so)
- struct socket *so;
-{
- /* Nothing, yet */
-}
-#endif
-
/*
* Various session state calls
* XXX Should be #define's
}
}
so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTSENDMORE)
- so->so_state = SS_NOFDREF; /* Don't select it */ /* XXX close() here as well? */
- else
+ if (so->so_state & SS_FCANTSENDMORE) {
+ so->so_state &= SS_PERSISTENT_MASK;
+ so->so_state |= SS_NOFDREF; /* Don't select it */
+ } else {
so->so_state |= SS_FCANTRCVMORE;
+ }
}
static void
}
}
so->so_state &= ~(SS_ISFCONNECTING);
- if (so->so_state & SS_FCANTRCVMORE)
- so->so_state = SS_NOFDREF; /* as above */
- else
+ if (so->so_state & SS_FCANTRCVMORE) {
+ so->so_state &= SS_PERSISTENT_MASK;
+ so->so_state |= SS_NOFDREF; /* as above */
+ } else {
so->so_state |= SS_FCANTSENDMORE;
-}
-
-void
-soisfdisconnected(struct socket *so)
-{
-/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */
-/* close(so->s); */
-/* so->so_state = SS_ISFDISCONNECTED; */
- /*
- * XXX Do nothing ... ?
- */
+ }
}
/*