From patchwork Fri Dec 11 20:02:41 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 555899 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 17D3E1401DA for ; Sat, 12 Dec 2015 07:03:10 +1100 (AEDT) Received: from localhost ([::1]:49325 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7TuF-0005dW-Um for incoming@patchwork.ozlabs.org; Fri, 11 Dec 2015 15:03:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59045) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7Ttx-0005DR-Bq for qemu-devel@nongnu.org; Fri, 11 Dec 2015 15:02:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a7Tts-0004dx-Aa for qemu-devel@nongnu.org; Fri, 11 Dec 2015 15:02:49 -0500 Received: from domu-toccata.ens-lyon.fr ([140.77.166.138]:38487 helo=sonata.ens-lyon.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a7Ttr-0004ds-Vt for qemu-devel@nongnu.org; Fri, 11 Dec 2015 15:02:44 -0500 Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id 9BD55200DA; Fri, 11 Dec 2015 21:02:42 +0100 (CET) Received: from sonata.ens-lyon.org ([127.0.0.1]) by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tjjLq8SfKm6P; Fri, 11 Dec 2015 21:02:42 +0100 (CET) Received: from var.ipv6 (ABordeaux-655-1-21-73.w86-222.abo.wanadoo.fr [86.222.244.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by sonata.ens-lyon.org (Postfix) with ESMTPSA id 327B5200D8; Fri, 11 Dec 2015 21:02:42 +0100 (CET) Received: from samy by var.ipv6 with local (Exim 4.86) (envelope-from ) id 1a7Ttp-0003qr-HM; Fri, 11 Dec 2015 21:02:41 +0100 Date: Fri, 11 Dec 2015 21:02:41 +0100 From: Samuel Thibault To: Thomas Huth Message-ID: <20151211200241.GO2764@var.home> References: <20151211001505.GV2905@var.home> <1449792930-27293-1-git-send-email-samuel.thibault@ens-lyon.org> <1449792930-27293-6-git-send-email-samuel.thibault@ens-lyon.org> <566AE66E.1030902@redhat.com> <20151211192944.GI2764@var.home> <20151211193819.GJ2764@var.home> <20151211195102.GK2764@var.home> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20151211195102.GK2764@var.home> User-Agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 140.77.166.138 Cc: zhanghailiang , Li Zhijian , Stefan Hajnoczi , Jason Wang , qemu-devel@nongnu.org, Vasiliy Tolstov , Dave Gilbert , Gonglei , Jan Kiszka , Huangpeng , Yang Hongyang , Guillaume Subiron Subject: Re: [Qemu-devel] [PATCH 06/18] slirp: Factorizing and cleaning solookup() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Samuel Thibault, on Fri 11 Dec 2015 20:51:02 +0100, wrote: > Samuel Thibault, on Fri 11 Dec 2015 20:38:19 +0100, wrote: > > I'll however have a look at introducing the optimizations etc. first, so > > that both making solookup use sockaddr and introducing sockaddr_equal > > looks natural. > > Yes, it seems to be working very nicely. Just FYI, here is how it looks like now. Samuel diff --git a/slirp/socket.c b/slirp/socket.c index 6382b6d..a4db442 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -15,29 +15,20 @@ static void sofcantrcvmore(struct socket *so); static void sofcantsendmore(struct socket *so); -struct socket * -solookup(struct socket **last, struct socket *head, - struct in_addr laddr, u_int lport, - struct in_addr faddr, u_int fport) +struct socket *solookup(struct socket **last, struct socket *head, + struct sockaddr_storage *lhost, struct sockaddr_storage *fhost) { struct socket *so = *last; /* Optimisation */ - if (so != head && - so->so_lport == lport && - so->so_laddr.s_addr == laddr.s_addr && - (!faddr.s_addr || - (so->so_faddr.s_addr == faddr.s_addr && - so->so_fport == fport))) { + if (so != head && sockaddr_equal(&(so->lhost.ss), lhost) + && (!fhost || sockaddr_equal(&(so->fhost.ss), fhost))) { return so; } for (so = head->so_next; so != head; so = so->so_next) { - if (so->so_lport == lport && - so->so_laddr.s_addr == laddr.s_addr && - (!faddr.s_addr || - (so->so_faddr.s_addr == faddr.s_addr && - so->so_fport == fport))) { + if (sockaddr_equal(&(so->lhost.ss), lhost) + && (!fhost || sockaddr_equal(&(so->fhost.ss), fhost))) { *last = so; return so; } diff --git a/slirp/socket.h b/slirp/socket.h index 3077581..8a23125 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -87,8 +87,27 @@ struct socket { #define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */ #define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */ -struct socket * solookup(struct socket **, struct socket *, - struct in_addr, u_int, struct in_addr, u_int); +static inline int sockaddr_equal(struct sockaddr_storage *a, + struct sockaddr_storage *b) +{ + if (a->ss_family != b->ss_family) + return 0; + + switch (a->ss_family) { + case AF_INET: + { + struct sockaddr_in *a4 = (struct sockaddr_in *) a; + struct sockaddr_in *b4 = (struct sockaddr_in *) b; + return (a4->sin_addr.s_addr == b4->sin_addr.s_addr + && a4->sin_port == b4->sin_port); + } + default: + assert(0); + } +} + +struct socket *solookup(struct socket **, struct socket *, + struct sockaddr_storage *, struct sockaddr_storage *); struct socket * socreate(Slirp *); void sofree(struct socket *); int soread(struct socket *); diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index 5492061..8c4fa62 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -227,6 +227,7 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso) int iss = 0; u_long tiwin; int ret; + struct sockaddr_storage lhost, fhost; struct ex_list *ex_ptr; Slirp *slirp; @@ -320,9 +321,14 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso) * Locate pcb for segment. */ findso: - so = solookup(&slirp->tcp_last_so, &slirp->tcb, - ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); + lhost.ss_family = AF_INET; + ((struct sockaddr_in *)&lhost)->sin_addr = ti->ti_src; + ((struct sockaddr_in *)&lhost)->sin_port = ti->ti_sport; + fhost.ss_family = AF_INET; + ((struct sockaddr_in *)&fhost)->sin_addr = ti->ti_dst; + ((struct sockaddr_in *)&fhost)->sin_port = ti->ti_dport; + + so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost); /* * If the state is CLOSED (i.e., TCB does not exist) then @@ -367,12 +373,8 @@ findso: sbreserve(&so->so_snd, TCP_SNDSPACE); sbreserve(&so->so_rcv, TCP_RCVSPACE); - so->so_lfamily = AF_INET; - so->so_laddr = ti->ti_src; - so->so_lport = ti->ti_sport; - so->so_ffamily = AF_INET; - so->so_faddr = ti->ti_dst; - so->so_fport = ti->ti_dport; + so->lhost.ss = lhost; + so->fhost.ss = fhost; if ((so->so_iptos = tcp_tos(so)) == 0) so->so_iptos = ((struct ip *)ti)->ip_tos; diff --git a/slirp/udp.c b/slirp/udp.c index 126ef82..f2dd773 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -70,6 +70,7 @@ udp_input(register struct mbuf *m, int iphlen) int len; struct ip save_ip; struct socket *so; + struct sockaddr_storage lhost; DEBUG_CALL("udp_input"); DEBUG_ARG("m = %p", m); @@ -151,8 +152,11 @@ udp_input(register struct mbuf *m, int iphlen) /* * Locate pcb for datagram. */ - so = solookup(&slirp->udp_last_so, &slirp->udb, - ip->ip_src, uh->uh_sport, (struct in_addr) {0}, 0); + lhost.ss_family = AF_INET; + ((struct sockaddr_in *)&lhost)->sin_addr = ip->ip_src; + ((struct sockaddr_in *)&lhost)->sin_port = uh->uh_sport; + + so = solookup(&slirp->udp_last_so, &slirp->udb, &lhost, NULL); if (so == NULL) { /* diff --git a/slirp/socket.c b/slirp/socket.c index 97948e8..6382b6d 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -16,23 +16,34 @@ static void sofcantrcvmore(struct socket *so); static void sofcantsendmore(struct socket *so); struct socket * -solookup(struct socket *head, struct in_addr laddr, u_int lport, +solookup(struct socket **last, struct socket *head, + struct in_addr laddr, u_int lport, struct in_addr faddr, u_int fport) { - struct socket *so; - - for (so = head->so_next; so != head; so = so->so_next) { - if (so->so_lport == lport && - so->so_laddr.s_addr == laddr.s_addr && - so->so_faddr.s_addr == faddr.s_addr && - so->so_fport == fport) - break; - } + struct socket *so = *last; + + /* Optimisation */ + if (so != head && + so->so_lport == lport && + so->so_laddr.s_addr == laddr.s_addr && + (!faddr.s_addr || + (so->so_faddr.s_addr == faddr.s_addr && + so->so_fport == fport))) { + return so; + } - if (so == head) - return (struct socket *)NULL; - return so; + for (so = head->so_next; so != head; so = so->so_next) { + if (so->so_lport == lport && + so->so_laddr.s_addr == laddr.s_addr && + (!faddr.s_addr || + (so->so_faddr.s_addr == faddr.s_addr && + so->so_fport == fport))) { + *last = so; + return so; + } + } + return (struct socket *)NULL; } /* diff --git a/slirp/socket.h b/slirp/socket.h index b27bbb2..3077581 100644 --- a/slirp/socket.h +++ b/slirp/socket.h @@ -87,7 +87,8 @@ struct socket { #define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */ #define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */ -struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int); +struct socket * solookup(struct socket **, struct socket *, + struct in_addr, u_int, struct in_addr, u_int); struct socket * socreate(Slirp *); void sofree(struct socket *); int soread(struct socket *); diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index 4c3191d..5492061 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -320,16 +320,9 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso) * Locate pcb for segment. */ findso: - so = slirp->tcp_last_so; - if (so->so_fport != ti->ti_dport || - so->so_lport != ti->ti_sport || - so->so_laddr.s_addr != ti->ti_src.s_addr || - so->so_faddr.s_addr != ti->ti_dst.s_addr) { - so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport, - ti->ti_dst, ti->ti_dport); - if (so) - slirp->tcp_last_so = so; - } + so = solookup(&slirp->tcp_last_so, &slirp->tcb, + ti->ti_src, ti->ti_sport, + ti->ti_dst, ti->ti_dport); /* * If the state is CLOSED (i.e., TCB does not exist) then diff --git a/slirp/udp.c b/slirp/udp.c index 8203eb1..126ef82 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -151,25 +151,8 @@ udp_input(register struct mbuf *m, int iphlen) /* * Locate pcb for datagram. */ - so = slirp->udp_last_so; - if (so == &slirp->udb || so->so_lport != uh->uh_sport || - so->so_laddr.s_addr != ip->ip_src.s_addr) { - struct socket *tmp; - - for (tmp = slirp->udb.so_next; tmp != &slirp->udb; - tmp = tmp->so_next) { - if (tmp->so_lport == uh->uh_sport && - tmp->so_laddr.s_addr == ip->ip_src.s_addr) { - so = tmp; - break; - } - } - if (tmp == &slirp->udb) { - so = NULL; - } else { - slirp->udp_last_so = so; - } - } + so = solookup(&slirp->udp_last_so, &slirp->udb, + ip->ip_src, uh->uh_sport, (struct in_addr) {0}, 0); if (so == NULL) { /*