summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/socket.test22
-rw-r--r--unix/tclUnixSock.c32
-rw-r--r--win/tclWinSock.c93
3 files changed, 104 insertions, 43 deletions
diff --git a/tests/socket.test b/tests/socket.test
index c50730c..d6cee30 100644
--- a/tests/socket.test
+++ b/tests/socket.test
@@ -2321,6 +2321,28 @@ test socket-14.15 {blocking read on async socket should not trigger event handle
set x
} -result ok
+# v4 and v6 is required to prevent that the async connect does not terminate
+# before the fconfigure command. There is always an additional ip to try.
+test socket-14.16 {empty -peername while [socket -async] connecting} \
+ -constraints {socket localhost_v4 localhost_v6} \
+ -body {
+ set client [socket -async localhost [randport]]
+ fconfigure $client -peername
+ } -cleanup {
+ catch {close $client}
+ } -result {}
+
+# v4 and v6 is required to prevent that the async connect does not terminate
+# before the fconfigure command. There is always an additional ip to try.
+test socket-14.17 {empty -sockname while [socket -async] connecting} \
+ -constraints {socket localhost_v4 localhost_v6} \
+ -body {
+ set client [socket -async localhost [randport]]
+ fconfigure $client -sockname
+ } -cleanup {
+ catch {close $client}
+ } -result {}
+
set num 0
set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}}
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index 96700ce..d06e7f1 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -823,7 +823,20 @@ TcpGetOptionProc(
address peername;
socklen_t size = sizeof(peername);
- if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) {
+ if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) {
+ /*
+ * In async connect output an empty string
+ */
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-peername");
+ Tcl_DStringAppendElement(dsPtr, "");
+ } else {
+ return TCL_OK;
+ }
+ } else if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) {
+ /*
+ * Peername fetch succeeded - output list
+ */
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-peername");
Tcl_DStringStartSublist(dsPtr);
@@ -863,11 +876,18 @@ TcpGetOptionProc(
Tcl_DStringAppendElement(dsPtr, "-sockname");
Tcl_DStringStartSublist(dsPtr);
}
- for (fds = &statePtr->fds; fds != NULL; fds = fds->next) {
- size = sizeof(sockname);
- if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) {
- found = 1;
- TcpHostPortList(interp, dsPtr, sockname, size);
+ if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) {
+ /*
+ * In async connect output an empty string
+ */
+ found = 1;
+ } else {
+ for (fds = &statePtr->fds; fds != NULL; fds = fds->next) {
+ size = sizeof(sockname);
+ if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) {
+ found = 1;
+ TcpHostPortList(interp, dsPtr, sockname, size);
+ }
}
}
if (found) {
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index f343f82..66df291 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -1337,7 +1337,20 @@ TcpGetOptionProc(
address peername;
socklen_t size = sizeof(peername);
- if (getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) {
+ if ( (statePtr->flags & TCP_ASYNC_PENDING) ) {
+ /*
+ * In async connect output an empty string
+ */
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-peername");
+ Tcl_DStringAppendElement(dsPtr, "");
+ } else {
+ return TCL_OK;
+ }
+ } else if ( getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) {
+ /*
+ * Peername fetch succeeded - output list
+ */
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-peername");
Tcl_DStringStartSublist(dsPtr);
@@ -1386,49 +1399,55 @@ TcpGetOptionProc(
Tcl_DStringAppendElement(dsPtr, "-sockname");
Tcl_DStringStartSublist(dsPtr);
}
- for (fds = statePtr->sockets; fds != NULL; fds = fds->next) {
- sock = fds->fd;
- size = sizeof(sockname);
- if (getsockname(sock, &(sockname.sa), &size) >= 0) {
- int flags = reverseDNS;
-
- found = 1;
- getnameinfo(&sockname.sa, size, host, sizeof(host),
- NULL, 0, NI_NUMERICHOST);
- Tcl_DStringAppendElement(dsPtr, host);
-
- /*
- * We don't want to resolve INADDR_ANY and sin6addr_any; they
- * can sometimes cause problems (and never have a name).
- */
- flags |= NI_NUMERICSERV;
- if (sockname.sa.sa_family == AF_INET) {
- if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) {
- flags |= NI_NUMERICHOST;
- }
- } else if (sockname.sa.sa_family == AF_INET6) {
- if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr,
- &in6addr_any)) ||
- (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr)
- && sockname.sa6.sin6_addr.s6_addr[12] == 0
- && sockname.sa6.sin6_addr.s6_addr[13] == 0
- && sockname.sa6.sin6_addr.s6_addr[14] == 0
- && sockname.sa6.sin6_addr.s6_addr[15] == 0)) {
- flags |= NI_NUMERICHOST;
+ if ( (statePtr->flags & TCP_ASYNC_PENDING ) ) {
+ /*
+ * In async connect output an empty string
+ */
+ found = 1;
+ } else {
+ for (fds = statePtr->sockets; fds != NULL; fds = fds->next) {
+ sock = fds->fd;
+ size = sizeof(sockname);
+ if (getsockname(sock, &(sockname.sa), &size) >= 0) {
+ int flags = reverseDNS;
+
+ found = 1;
+ getnameinfo(&sockname.sa, size, host, sizeof(host),
+ NULL, 0, NI_NUMERICHOST);
+ Tcl_DStringAppendElement(dsPtr, host);
+
+ /*
+ * We don't want to resolve INADDR_ANY and sin6addr_any; they
+ * can sometimes cause problems (and never have a name).
+ */
+ flags |= NI_NUMERICSERV;
+ if (sockname.sa.sa_family == AF_INET) {
+ if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) {
+ flags |= NI_NUMERICHOST;
+ }
+ } else if (sockname.sa.sa_family == AF_INET6) {
+ if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr,
+ &in6addr_any)) ||
+ (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr)
+ && sockname.sa6.sin6_addr.s6_addr[12] == 0
+ && sockname.sa6.sin6_addr.s6_addr[13] == 0
+ && sockname.sa6.sin6_addr.s6_addr[14] == 0
+ && sockname.sa6.sin6_addr.s6_addr[15] == 0)) {
+ flags |= NI_NUMERICHOST;
+ }
}
+ getnameinfo(&sockname.sa, size, host, sizeof(host),
+ port, sizeof(port), flags);
+ Tcl_DStringAppendElement(dsPtr, host);
+ Tcl_DStringAppendElement(dsPtr, port);
}
- getnameinfo(&sockname.sa, size, host, sizeof(host),
- port, sizeof(port), flags);
- Tcl_DStringAppendElement(dsPtr, host);
- Tcl_DStringAppendElement(dsPtr, port);
}
}
if (found) {
- if (len == 0) {
- Tcl_DStringEndSublist(dsPtr);
- } else {
+ if (len) {
return TCL_OK;
}
+ Tcl_DStringEndSublist(dsPtr);
} else {
if (interp) {
TclWinConvertError((DWORD) WSAGetLastError());