You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@locus.apache.org on 2000/08/01 22:59:53 UTC
cvs commit: apache-2.0/src/lib/apr/network_io/win32 networkio.h sockaddr.c sockets.c
trawick 00/08/01 13:59:53
Modified: src CHANGES
src/lib/apr/network_io/win32 networkio.h sockaddr.c
sockets.c
Log:
Fix problems with APR sockaddr handling on Win32. It didn't always
return the right information on the local socket address. This
change uses the Unix logic for delaying/avoiding getsockname() to
ensure that it is done when needed.
Submitted by: Gregory Nicholls <gn...@level8.com>
Reviewed by: Jeff Trawick
Revision Changes Path
1.190 +4 -0 apache-2.0/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-2.0/src/CHANGES,v
retrieving revision 1.189
retrieving revision 1.190
diff -u -r1.189 -r1.190
--- CHANGES 2000/08/01 19:33:15 1.189
+++ CHANGES 2000/08/01 20:59:51 1.190
@@ -1,4 +1,8 @@
Changes with Apache 2.0a5
+ *) Fix problems with APR sockaddr handling on Win32. It didn't always
+ return the right information on the local socket address.
+ [Gregory Nicholls <gn...@level8.com>]
+
*) ap_recv() on Win32: Set bytes-read to 0 on error.
[Gregory Nicholls <gn...@level8.com>]
1.12 +2 -0 apache-2.0/src/lib/apr/network_io/win32/networkio.h
Index: networkio.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/networkio.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- networkio.h 2000/07/06 15:13:25 1.11
+++ networkio.h 2000/08/01 20:59:52 1.12
@@ -66,6 +66,8 @@
size_t addr_len;
ap_interval_time_t timeout;
ap_int32_t disconnected;
+ int local_port_unknown;
+ int local_interface_unknown;
};
struct ap_pollfd_t {
1.10 +39 -0 apache-2.0/src/lib/apr/network_io/win32/sockaddr.c
Index: sockaddr.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockaddr.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- sockaddr.c 2000/07/25 00:42:13 1.9
+++ sockaddr.c 2000/08/01 20:59:52 1.10
@@ -58,7 +58,22 @@
#include "apr_strings.h"
#include <string.h>
+static ap_status_t get_local_addr(ap_socket_t *sock)
+{
+ size_t namelen = sizeof(*sock->local_addr);
+ if (getsockname(sock->sock, (struct sockaddr *)sock->local_addr,
+ &namelen) < 0) {
+ return WSAGetLastError();
+ }
+ else {
+ sock->local_port_unknown = sock->local_interface_unknown = 0;
+ return APR_SUCCESS;
+ }
+}
+
+
+
ap_status_t ap_set_local_port(ap_socket_t *sock, ap_uint32_t port)
{
sock->local_addr->sin_port = htons((short)port);
@@ -77,6 +92,14 @@
ap_status_t ap_get_local_port(ap_uint32_t *port, ap_socket_t *sock)
{
+ if (sock->local_port_unknown) {
+ ap_status_t rv = get_local_addr(sock);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ }
+
*port = ntohs(sock->local_addr->sin_port);
return APR_SUCCESS;
}
@@ -131,6 +154,14 @@
ap_status_t ap_get_local_ipaddr(char **addr, ap_socket_t *sock)
{
+ if (sock->local_interface_unknown) {
+ ap_status_t rv = get_local_addr(sock);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ }
+
*addr = ap_pstrdup(sock->cntxt, inet_ntoa(sock->local_addr->sin_addr));
return APR_SUCCESS;
}
@@ -146,6 +177,14 @@
ap_status_t ap_get_local_name(struct sockaddr_in **name, ap_socket_t *sock)
{
+ if (sock->local_port_unknown || sock->local_interface_unknown) {
+ ap_status_t rv = get_local_addr(sock);
+
+ if (rv != APR_SUCCESS) {
+ return rv;
+ }
+ }
+
*name = sock->local_addr;
return APR_SUCCESS;
}
1.35 +42 -12 apache-2.0/src/lib/apr/network_io/win32/sockets.c
Index: sockets.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockets.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- sockets.c 2000/07/25 15:50:52 1.34
+++ sockets.c 2000/08/01 20:59:52 1.35
@@ -150,8 +150,12 @@
if (bind(sock->sock, (struct sockaddr *)sock->local_addr, sock->addr_len) == -1) {
return WSAGetLastError();
}
- else
+ else {
+ if (sock->local_addr->sin_port == 0) {
+ sock->local_port_unknown = 1; /* ephemeral port */
+ }
return APR_SUCCESS;
+ }
}
ap_status_t ap_listen(ap_socket_t *sock, ap_int32_t backlog)
@@ -185,6 +189,24 @@
return WSAGetLastError();
}
+ *(*new)->local_addr = *sock->local_addr;
+
+ if (sock->local_port_unknown) {
+ /* not likely for a listening socket, but theoretically possible :) */
+ (*new)->local_port_unknown = 1;
+ }
+
+ if (sock->local_interface_unknown ||
+ sock->local_addr->sin_addr.s_addr == 0) {
+ /* If the interface address inside the listening socket's local_addr wasn't
+ * up-to-date, we don't know local interface of the connected socket either.
+ *
+ * If the listening socket was not bound to a specific interface, we
+ * don't know the local_addr of the connected socket.
+ */
+ (*new)->local_interface_unknown = 1;
+ }
+
ap_register_cleanup((*new)->cntxt, (void *)(*new),
socket_cleanup, ap_null_cleanup);
return APR_SUCCESS;
@@ -218,20 +240,27 @@
sock->remote_addr->sin_family = AF_INET;
if (connect(sock->sock, (const struct sockaddr *)sock->remote_addr,
- sock->addr_len) == 0) {
- return APR_SUCCESS;
- }
- else {
+ sock->addr_len) == SOCKET_ERROR) {
lasterror = WSAGetLastError();
- if (lasterror == WSAEWOULDBLOCK) {
- FD_ZERO(&temp);
- FD_SET(sock->sock, &temp);
- if (select(sock->sock+1, NULL, &temp, NULL, NULL) == 1) {
- return APR_SUCCESS;
- }
+ if (lasterror != WSAEWOULDBLOCK) {
+ return lasterror;
}
- return lasterror;
+ /* wait for the connect to complete */
+ FD_ZERO(&temp);
+ FD_SET(sock->sock, &temp);
+ if (select(sock->sock+1, NULL, &temp, NULL, NULL) == SOCKET_ERROR) {
+ return WSAGetLastError();
+ }
+ }
+ /* connect was OK .. amazing */
+ if (sock->local_addr->sin_port == 0) {
+ sock->local_port_unknown = 1;
+ }
+ if (sock->local_addr->sin_addr.s_addr == 0) {
+ /* must be using free-range port */
+ sock->local_interface_unknown = 1;
}
+ return APR_SUCCESS;
}
ap_status_t ap_get_socketdata(void **data, const char *key, ap_socket_t *socket)
@@ -273,6 +302,7 @@
(*sock)->timeout = -1;
(*sock)->disconnected = 0;
}
+ (*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
(*sock)->sock = *thesock;
return APR_SUCCESS;
}