diff mbox

[PATCHv7,5/9] slirp: Generalizing and neutralizing various TCP functions before adding IPv6 stuff

Message ID 145e7741b4d6eeac3d69ea9cf40110229167db0c.1454927009.git.samuel.thibault@ens-lyon.org
State New
Headers show

Commit Message

Samuel Thibault Feb. 8, 2016, 10:28 a.m. UTC
From: Guillaume Subiron <maethor@subiron.org>

Basically, this patch adds some switch in various TCP functions to
prepare them for the IPv6 case.

To have something to "switch" in tcp_input() and tcp_respond(), a new
argument is used to give them the sa_family of the addresses they are
working on.

This patch does not include the entailed reindentation, to make proofread
easier. Reindentation is adressed in the following no-op patch.

Signed-off-by: Guillaume Subiron <maethor@subiron.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 slirp/ip_input.c   |  2 +-
 slirp/slirp.c      |  6 ++++--
 slirp/slirp.h      |  5 +++--
 slirp/tcp_input.c  | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
 slirp/tcp_output.c | 14 +++++++++++---
 slirp/tcp_subr.c   | 37 +++++++++++++++++++++++++++++--------
 slirp/tcp_timer.c  |  3 ++-
 7 files changed, 94 insertions(+), 25 deletions(-)

Comments

Thomas Huth Feb. 10, 2016, 8:35 a.m. UTC | #1
On 08.02.2016 11:28, Samuel Thibault wrote:
> From: Guillaume Subiron <maethor@subiron.org>
> 
> Basically, this patch adds some switch in various TCP functions to
> prepare them for the IPv6 case.
> 
> To have something to "switch" in tcp_input() and tcp_respond(), a new
> argument is used to give them the sa_family of the addresses they are
> working on.
> 
> This patch does not include the entailed reindentation, to make proofread
> easier. Reindentation is adressed in the following no-op patch.
> 
> Signed-off-by: Guillaume Subiron <maethor@subiron.org>
> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
> ---
>  slirp/ip_input.c   |  2 +-
>  slirp/slirp.c      |  6 ++++--
>  slirp/slirp.h      |  5 +++--
>  slirp/tcp_input.c  | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
>  slirp/tcp_output.c | 14 +++++++++++---
>  slirp/tcp_subr.c   | 37 +++++++++++++++++++++++++++++--------
>  slirp/tcp_timer.c  |  3 ++-
>  7 files changed, 94 insertions(+), 25 deletions(-)
...
> diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
> index 26b0c8b..0cc279b 100644
> --- a/slirp/tcp_input.c
> +++ b/slirp/tcp_input.c
> @@ -214,7 +214,7 @@ present:
>   * protocol specification dated September, 1981 very closely.
>   */
>  void
> -tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
> +tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
>  {
>    	struct ip save_ip, *ip;
>  	register struct tcpiphdr *ti;
> @@ -256,6 +256,8 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
>  	}
>  	slirp = m->slirp;
>  
> +	switch (af) {
> +	case AF_INET:
>  	if (iphlen > sizeof(struct ip )) {
>  	  ip_stripoptions(m, (struct mbuf *)0);
>  	  iphlen=sizeof(struct ip );
> @@ -297,6 +299,11 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
>  	if(cksum(m, len)) {
>  	  goto drop;
>  	}
> +	break;
> +
> +	default:
> +	    goto drop;
> +	}
>  
>  	/*
>  	 * Check that TCP offset makes sense,
> @@ -332,14 +339,20 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
>  	 * Locate pcb for segment.
>  	 */
>  findso:
> -	lhost.ss_family = AF_INET;
> +	lhost.ss_family = af;
> +	fhost.ss_family = af;
> +	switch (af) {
> +	case AF_INET:
>  	lhost4 = (struct sockaddr_in *) &lhost;
>  	lhost4->sin_addr = ti->ti_src;
>  	lhost4->sin_port = ti->ti_sport;
> -	fhost.ss_family = AF_INET;
>  	fhost4 = (struct sockaddr_in *) &fhost;
>  	fhost4->sin_addr = ti->ti_dst;
>  	fhost4->sin_port = ti->ti_dport;
> +	    break;
> +	default:
> +	    goto drop;
> +	}
>  
>  	so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost);
>  
> @@ -389,8 +402,17 @@ findso:
>  	  so->lhost.ss = lhost;
>  	  so->fhost.ss = fhost;
>  
> -	  if ((so->so_iptos = tcp_tos(so)) == 0)
> +	  so->so_iptos = tcp_tos(so);
> +	  if (so->so_iptos == 0) {
> +	      switch (af) {
> +	      case AF_INET:
>  	    so->so_iptos = ((struct ip *)ti)->ip_tos;

I think you could also indent this here immediately ... it's only one
line, so indenting immediately should not hurt readability here.

> +	          break;
> +	      default:
> +	          goto drop;
> +	          break;
> +	      }
> +	  }
>  
>  	  tp = sototcpcb(so);
>  	  tp->t_state = TCPS_LISTEN;
> @@ -569,7 +591,8 @@ findso:
>  	   * If this is destined for the control address, then flag to
>  	   * tcp_ctl once connected, otherwise connect
>  	   */
> -	  if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
> +	  if (af == AF_INET &&
> +	      (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
>  	      slirp->vnetwork_addr.s_addr) {
>  	    if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
>  		so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
> @@ -607,7 +630,7 @@ findso:
>  	    if(errno == ECONNREFUSED) {
>  	      /* ACK the SYN, send RST to refuse the connection */
>  	      tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
> -			  TH_RST|TH_ACK);
> +			  TH_RST|TH_ACK, af);
>  	    } else {
>  	      if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
>  	      HTONL(ti->ti_seq);             /* restore tcp header */
> @@ -616,7 +639,13 @@ findso:
>  	      HTONS(ti->ti_urp);
>  	      m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
>  	      m->m_len  += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
> +	      switch (af) {
> +	      case AF_INET:
>  	      *ip=save_ip;

Could also be indented immediately.

> +	          break;
> +	      default:
> +	          goto drop;
> +	      }
>  	      icmp_send_error(m, ICMP_UNREACH, code, 0, strerror(errno));
>  	    }
>              tcp_close(tp);
> @@ -1289,11 +1318,11 @@ dropafterack:
>  dropwithreset:
>  	/* reuses m if m!=NULL, m_free() unnecessary */
>  	if (tiflags & TH_ACK)
> -		tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
> +		tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST, af);
>  	else {
>  		if (tiflags & TH_SYN) ti->ti_len++;
>  		tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
> -		    TH_RST|TH_ACK);
> +		    TH_RST|TH_ACK, af);
>  	}
>  
>  	return;
> @@ -1484,7 +1513,14 @@ tcp_mss(struct tcpcb *tp, u_int offer)
>  	DEBUG_ARG("tp = %p", tp);
>  	DEBUG_ARG("offer = %d", offer);
>  
> +	switch (so->so_ffamily) {
> +	case AF_INET:
>  	mss = min(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + sizeof(struct ip);

dito, indent immediately.

> +	    break;
> +	default:
> +	    break;
> +	}
> +
>  	if (offer)
>  		mss = min(mss, offer);
>  	mss = max(mss, 32);
> diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
> index 7fc6a87..62ab1e5 100644
> --- a/slirp/tcp_output.c
> +++ b/slirp/tcp_output.c
> @@ -61,7 +61,8 @@ tcp_output(struct tcpcb *tp)
>  	register long len, win;
>  	int off, flags, error;
>  	register struct mbuf *m;
> -	register struct tcpiphdr *ti;
> +	register struct tcpiphdr *ti, tcpiph_save;
> +	struct ip *ip;
>  	u_char opt[MAX_TCPOPTLEN];
>  	unsigned optlen, hdrlen;
>  	int idle, sendalot;
> @@ -447,13 +448,15 @@ send:
>  	 * the template, but need a way to checksum without them.
>  	 */
>  	m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
> +	tcpiph_save = *(mtod(m, struct tcpiphdr *));
>  
> -	struct tcpiphdr tcpiph_save = *(mtod(m, struct tcpiphdr *));
> +	switch (so->so_ffamily) {
> +	case AF_INET:
>  	m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
>  	                                     - sizeof(struct ip);
>  	m->m_len  -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
>  	                                     - sizeof(struct ip);
> -	struct ip *ip = mtod(m, struct ip *);
> +	ip = mtod(m, struct ip *);
>  
>  	ip->ip_len = m->m_len;
>  	ip->ip_dst = tcpiph_save.ti_dst;
> @@ -464,6 +467,11 @@ send:
>  	ip->ip_tos = so->so_iptos;
>  
>  	error = ip_output(so, m);
> +	    break;
> +
> +	default:
> +	    goto out;

Hmm, this jumps to a "return (error)" statement ... but as far as I can
see, error has never been initialized in this case? So I think you
either should set the error variable explicitely here, or simply "return
1" immediately instead of doing the goto.

> +	}
>  
>  	if (error) {
>  out:

 Thomas
Samuel Thibault Feb. 10, 2016, 9:17 a.m. UTC | #2
Thomas Huth, on Wed 10 Feb 2016 09:35:31 +0100, wrote:
> Hmm, this jumps to a "return (error)" statement ... but as far as I can
> see, error has never been initialized in this case?

Actually those places are unreachable (the address family can only be
INET at this point, and only INET or INET6 once tcpv6 is added). I'll
use g_assert_not_reached() instead.

Samuel
diff mbox

Patch

diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 16fb2cb..12f173d 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -200,7 +200,7 @@  ip_input(struct mbuf *m)
 	 */
 	switch (ip->ip_p) {
 	 case IPPROTO_TCP:
-		tcp_input(m, hlen, (struct socket *)NULL);
+		tcp_input(m, hlen, (struct socket *)NULL, AF_INET);
 		break;
 	 case IPPROTO_UDP:
 		udp_input(m, hlen);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 551f100..cca5a80 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -573,7 +573,8 @@  void slirp_pollfds_poll(GArray *pollfds, int select_error)
                         /*
                          * Continue tcp_input
                          */
-                        tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
+                        tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
+                                so->so_ffamily);
                         /* continue; */
                     } else {
                         ret = sowrite(so);
@@ -622,7 +623,8 @@  void slirp_pollfds_poll(GArray *pollfds, int select_error)
                         }
 
                     }
-                    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);
+                    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so,
+                            so->so_ffamily);
                 } /* SS_ISFCONNECTING */
 #endif
             }
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 1772222..3261815 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -346,7 +346,7 @@  void ip6_input(struct mbuf *);
 int ip6_output(struct socket *, struct mbuf *, int fast);
 
 /* tcp_input.c */
-void tcp_input(register struct mbuf *, int, struct socket *);
+void tcp_input(register struct mbuf *, int, struct socket *, unsigned short af);
 int tcp_mss(register struct tcpcb *, u_int);
 
 /* tcp_output.c */
@@ -357,7 +357,8 @@  void tcp_setpersist(register struct tcpcb *);
 void tcp_init(Slirp *);
 void tcp_cleanup(Slirp *);
 void tcp_template(struct tcpcb *);
-void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int);
+void tcp_respond(struct tcpcb *, register struct tcpiphdr *,
+        register struct mbuf *, tcp_seq, tcp_seq, int, unsigned short);
 struct tcpcb * tcp_newtcpcb(struct socket *);
 struct tcpcb * tcp_close(register struct tcpcb *);
 void tcp_sockclosed(struct tcpcb *);
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 26b0c8b..0cc279b 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -214,7 +214,7 @@  present:
  * protocol specification dated September, 1981 very closely.
  */
 void
-tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
+tcp_input(struct mbuf *m, int iphlen, struct socket *inso, unsigned short af)
 {
   	struct ip save_ip, *ip;
 	register struct tcpiphdr *ti;
@@ -256,6 +256,8 @@  tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	}
 	slirp = m->slirp;
 
+	switch (af) {
+	case AF_INET:
 	if (iphlen > sizeof(struct ip )) {
 	  ip_stripoptions(m, (struct mbuf *)0);
 	  iphlen=sizeof(struct ip );
@@ -297,6 +299,11 @@  tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	if(cksum(m, len)) {
 	  goto drop;
 	}
+	break;
+
+	default:
+	    goto drop;
+	}
 
 	/*
 	 * Check that TCP offset makes sense,
@@ -332,14 +339,20 @@  tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
 	 * Locate pcb for segment.
 	 */
 findso:
-	lhost.ss_family = AF_INET;
+	lhost.ss_family = af;
+	fhost.ss_family = af;
+	switch (af) {
+	case AF_INET:
 	lhost4 = (struct sockaddr_in *) &lhost;
 	lhost4->sin_addr = ti->ti_src;
 	lhost4->sin_port = ti->ti_sport;
-	fhost.ss_family = AF_INET;
 	fhost4 = (struct sockaddr_in *) &fhost;
 	fhost4->sin_addr = ti->ti_dst;
 	fhost4->sin_port = ti->ti_dport;
+	    break;
+	default:
+	    goto drop;
+	}
 
 	so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost);
 
@@ -389,8 +402,17 @@  findso:
 	  so->lhost.ss = lhost;
 	  so->fhost.ss = fhost;
 
-	  if ((so->so_iptos = tcp_tos(so)) == 0)
+	  so->so_iptos = tcp_tos(so);
+	  if (so->so_iptos == 0) {
+	      switch (af) {
+	      case AF_INET:
 	    so->so_iptos = ((struct ip *)ti)->ip_tos;
+	          break;
+	      default:
+	          goto drop;
+	          break;
+	      }
+	  }
 
 	  tp = sototcpcb(so);
 	  tp->t_state = TCPS_LISTEN;
@@ -569,7 +591,8 @@  findso:
 	   * If this is destined for the control address, then flag to
 	   * tcp_ctl once connected, otherwise connect
 	   */
-	  if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+	  if (af == AF_INET &&
+	      (so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
 	      slirp->vnetwork_addr.s_addr) {
 	    if (so->so_faddr.s_addr != slirp->vhost_addr.s_addr &&
 		so->so_faddr.s_addr != slirp->vnameserver_addr.s_addr) {
@@ -607,7 +630,7 @@  findso:
 	    if(errno == ECONNREFUSED) {
 	      /* ACK the SYN, send RST to refuse the connection */
 	      tcp_respond(tp, ti, m, ti->ti_seq+1, (tcp_seq)0,
-			  TH_RST|TH_ACK);
+			  TH_RST|TH_ACK, af);
 	    } else {
 	      if(errno == EHOSTUNREACH) code=ICMP_UNREACH_HOST;
 	      HTONL(ti->ti_seq);             /* restore tcp header */
@@ -616,7 +639,13 @@  findso:
 	      HTONS(ti->ti_urp);
 	      m->m_data -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
 	      m->m_len  += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
+	      switch (af) {
+	      case AF_INET:
 	      *ip=save_ip;
+	          break;
+	      default:
+	          goto drop;
+	      }
 	      icmp_send_error(m, ICMP_UNREACH, code, 0, strerror(errno));
 	    }
             tcp_close(tp);
@@ -1289,11 +1318,11 @@  dropafterack:
 dropwithreset:
 	/* reuses m if m!=NULL, m_free() unnecessary */
 	if (tiflags & TH_ACK)
-		tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST);
+		tcp_respond(tp, ti, m, (tcp_seq)0, ti->ti_ack, TH_RST, af);
 	else {
 		if (tiflags & TH_SYN) ti->ti_len++;
 		tcp_respond(tp, ti, m, ti->ti_seq+ti->ti_len, (tcp_seq)0,
-		    TH_RST|TH_ACK);
+		    TH_RST|TH_ACK, af);
 	}
 
 	return;
@@ -1484,7 +1513,14 @@  tcp_mss(struct tcpcb *tp, u_int offer)
 	DEBUG_ARG("tp = %p", tp);
 	DEBUG_ARG("offer = %d", offer);
 
+	switch (so->so_ffamily) {
+	case AF_INET:
 	mss = min(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + sizeof(struct ip);
+	    break;
+	default:
+	    break;
+	}
+
 	if (offer)
 		mss = min(mss, offer);
 	mss = max(mss, 32);
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 7fc6a87..62ab1e5 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -61,7 +61,8 @@  tcp_output(struct tcpcb *tp)
 	register long len, win;
 	int off, flags, error;
 	register struct mbuf *m;
-	register struct tcpiphdr *ti;
+	register struct tcpiphdr *ti, tcpiph_save;
+	struct ip *ip;
 	u_char opt[MAX_TCPOPTLEN];
 	unsigned optlen, hdrlen;
 	int idle, sendalot;
@@ -447,13 +448,15 @@  send:
 	 * the template, but need a way to checksum without them.
 	 */
 	m->m_len = hdrlen + len; /* XXX Needed? m_len should be correct */
+	tcpiph_save = *(mtod(m, struct tcpiphdr *));
 
-	struct tcpiphdr tcpiph_save = *(mtod(m, struct tcpiphdr *));
+	switch (so->so_ffamily) {
+	case AF_INET:
 	m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 	                                     - sizeof(struct ip);
 	m->m_len  -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 	                                     - sizeof(struct ip);
-	struct ip *ip = mtod(m, struct ip *);
+	ip = mtod(m, struct ip *);
 
 	ip->ip_len = m->m_len;
 	ip->ip_dst = tcpiph_save.ti_dst;
@@ -464,6 +467,11 @@  send:
 	ip->ip_tos = so->so_iptos;
 
 	error = ip_output(so, m);
+	    break;
+
+	default:
+	    goto out;
+	}
 
 	if (error) {
 out:
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index cd021df..f1d62f6 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -78,12 +78,19 @@  tcp_template(struct tcpcb *tp)
 	n->ti_mbuf = NULL;
 	memset(&n->ti, 0, sizeof(n->ti));
 	n->ti_x0 = 0;
+	switch (so->so_ffamily) {
+	case AF_INET:
 	n->ti_pr = IPPROTO_TCP;
 	n->ti_len = htons(sizeof(struct tcphdr));
 	n->ti_src = so->so_faddr;
 	n->ti_dst = so->so_laddr;
 	n->ti_sport = so->so_fport;
 	n->ti_dport = so->so_lport;
+	    break;
+
+	default:
+	    break;
+	}
 
 	n->ti_seq = 0;
 	n->ti_ack = 0;
@@ -110,7 +117,7 @@  tcp_template(struct tcpcb *tp)
  */
 void
 tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
-            tcp_seq ack, tcp_seq seq, int flags)
+            tcp_seq ack, tcp_seq seq, int flags, unsigned short af)
 {
 	register int tlen;
 	int win = 0;
@@ -144,8 +151,14 @@  tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
 		m->m_len = sizeof (struct tcpiphdr);
 		tlen = 0;
 #define xchg(a,b,type) { type t; t=a; a=b; b=t; }
+		switch (af) {
+		case AF_INET:
 		xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, uint32_t);
 		xchg(ti->ti_dport, ti->ti_sport, uint16_t);
+		    break;
+		default:
+		    break;
+		}
 #undef xchg
 	}
 	ti->ti_len = htons((u_short)(sizeof (struct tcphdr) + tlen));
@@ -168,11 +181,15 @@  tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
 	ti->ti_sum = cksum(m, tlen);
 
 	struct tcpiphdr tcpiph_save = *(mtod(m, struct tcpiphdr *));
+	struct ip *ip;
+
+	switch (af) {
+	case AF_INET:
 	m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 	                                     - sizeof(struct ip);
 	m->m_len  -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
 	                                     - sizeof(struct ip);
-	struct ip *ip = mtod(m, struct ip *);
+	ip = mtod(m, struct ip *);
 	ip->ip_len = tlen;
 	ip->ip_dst = tcpiph_save.ti_dst;
 	ip->ip_src = tcpiph_save.ti_src;
@@ -185,6 +202,11 @@  tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
 	}
 
 	(void) ip_output((struct socket *)0, m);
+	    break;
+
+	default:
+	    break;
+	}
 }
 
 /*
@@ -388,8 +410,8 @@  void tcp_connect(struct socket *inso)
 {
     Slirp *slirp = inso->slirp;
     struct socket *so;
-    struct sockaddr_in addr;
-    socklen_t addrlen = sizeof(struct sockaddr_in);
+    struct sockaddr_storage addr;
+    socklen_t addrlen = sizeof(struct sockaddr_storage);
     struct tcpcb *tp;
     int s, opt;
 
@@ -414,9 +436,8 @@  void tcp_connect(struct socket *inso)
             free(so); /* NOT sofree */
             return;
         }
-        so->so_lfamily = AF_INET;
-        so->so_laddr = inso->so_laddr;
-        so->so_lport = inso->so_lport;
+        so->lhost = inso->lhost;
+        so->so_ffamily = inso->so_ffamily;
     }
 
     tcp_mss(sototcpcb(so), 0);
@@ -432,7 +453,7 @@  void tcp_connect(struct socket *inso)
     qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
     socket_set_nodelay(s);
 
-    so->fhost.sin = addr;
+    so->fhost.ss = addr;
     sotranslate_accept(so);
 
     /* Close the accept() socket, set right state */
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index 1214c2e..8f5dd77 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -278,7 +278,8 @@  tcp_timers(register struct tcpcb *tp, int timer)
 			 * correspondent TCP to respond.
 			 */
 			tcp_respond(tp, &tp->t_template, (struct mbuf *)NULL,
-			    tp->rcv_nxt, tp->snd_una - 1, 0);
+			    tp->rcv_nxt, tp->snd_una - 1, 0,
+			    tp->t_socket->so_ffamily);
 			tp->t_timer[TCPT_KEEP] = TCPTV_KEEPINTVL;
 		} else
 			tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_IDLE;