summaryrefslogtreecommitdiff
path: root/slirp/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'slirp/socket.c')
-rw-r--r--slirp/socket.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/slirp/socket.c b/slirp/socket.c
index d1034fb536..8f73e906e2 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;
}
/*