aboutsummaryrefslogtreecommitdiff
path: root/src/tcp_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcp_subr.c')
-rw-r--r--src/tcp_subr.c33
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()