diff options
Diffstat (limited to 'src/tcp_subr.c')
-rw-r--r-- | src/tcp_subr.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/tcp_subr.c b/src/tcp_subr.c index b4777ce..600cfa1 100644 --- a/src/tcp_subr.c +++ b/src/tcp_subr.c @@ -466,10 +466,41 @@ void tcp_connect(struct socket *inso) struct sockaddr_storage addr; socklen_t addrlen = sizeof(struct sockaddr_storage); struct tcpcb *tp; - int s, opt; + int s, opt, ret; + /* AF_INET6 addresses are bigger than AF_INET, so this is big enough. */ + char addrstr[INET6_ADDRSTRLEN]; + char portstr[6]; DEBUG_CALL("tcp_connect"); DEBUG_ARG("inso = %p", inso); + ret = getnameinfo((const struct sockaddr *) &inso->lhost.ss, sizeof(inso->lhost.ss), addrstr, sizeof(addrstr), portstr, sizeof(portstr), NI_NUMERICHOST|NI_NUMERICSERV); + g_assert(ret == 0); + DEBUG_ARG("ip = [%s]:%s", addrstr, portstr); + DEBUG_ARG("so_state = 0x%x", inso->so_state); + + /* Perform lazy guest IP address resolution if needed. */ + if (inso->so_state & SS_HOSTFWD) { + /* + * We can only reject the connection request by accepting it and + * then immediately closing it. Note that SS_FACCEPTONCE sockets can't + * get here. + */ + if (soassign_guest_addr_if_needed(inso) < 0) { + /* + * Guest address isn't available yet. We could either try to defer + * completing this connection request until the guest address is + * available, or punt. It's easier to punt. Otherwise we need to + * complicate the mechanism by which we're called to defer calling + * us again until the guest address is available. + */ + DEBUG_MISC(" guest address not available yet"); + s = accept(inso->s, (struct sockaddr *)&addr, &addrlen); + if (s >= 0) { + close(s); + } + return; + } + } /* * If it's an SS_ACCEPTONCE socket, no need to socreate() |