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/06/29 00:36:31 UTC
cvs commit: apache-2.0/src/lib/apr/network_io/unix networkio.h sockaddr.c sockets.c
trawick 00/06/28 15:36:30
Modified: src/lib/apr/network_io/unix networkio.h sockaddr.c sockets.c
Log:
APR network_io for Unix:
Defer/avoid getsockname() whenever possible.
Revision Changes Path
1.30 +2 -0 apache-2.0/src/lib/apr/network_io/unix/networkio.h
Index: networkio.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/networkio.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -r1.29 -r1.30
--- networkio.h 2000/06/22 00:36:04 1.29
+++ networkio.h 2000/06/28 22:36:28 1.30
@@ -126,6 +126,8 @@
#ifndef HAVE_POLL
int connected;
#endif
+ int local_port_unknown;
+ int local_interface_unknown;
};
struct ap_pollfd_t {
1.13 +40 -0 apache-2.0/src/lib/apr/network_io/unix/sockaddr.c
Index: sockaddr.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockaddr.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- sockaddr.c 2000/06/26 20:37:42 1.12
+++ sockaddr.c 2000/06/28 22:36:28 1.13
@@ -70,8 +70,32 @@
+static ap_status_t get_local_addr(ap_socket_t *sock)
+{
+ socklen_t namelen = sizeof(*sock->local_addr);
+
+ if (getsockname(sock->socketdes, (struct sockaddr *)sock->local_addr,
+ &namelen) < 0) {
+ return errno;
+ }
+ else {
+ sock->local_port_unknown = sock->local_interface_unknown = 0;
+ return APR_SUCCESS;
+ }
+}
+
+
+
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;
}
@@ -130,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;
}
@@ -147,6 +179,14 @@
#if APR_HAVE_NETINET_IN_H
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.50 +32 -10 apache-2.0/src/lib/apr/network_io/unix/sockets.c
Index: sockets.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- sockets.c 2000/06/26 20:37:42 1.49
+++ sockets.c 2000/06/28 22:36:28 1.50
@@ -115,8 +115,12 @@
{
if (bind(sock->socketdes, (struct sockaddr *)sock->local_addr, sock->addr_len) == -1)
return errno;
- else
+ else {
+ if (sock->local_addr->sin_port == 0) { /* no need for ntohs() when comparing w/ 0 */
+ sock->local_port_unknown = 1; /* kernel got us an ephemeral port */
+ }
return APR_SUCCESS;
+ }
}
ap_status_t ap_listen(ap_socket_t *sock, ap_int32_t backlog)
@@ -151,9 +155,22 @@
return errno;
}
- if (getsockname((*new)->socketdes, (struct sockaddr *)(*new)->local_addr,
- &((*new)->addr_len)) < 0) {
- return errno;
+ *(*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),
@@ -197,8 +214,16 @@
return errno;
}
else {
- socklen_t namelen = sizeof(*sock->local_addr);
- getsockname(sock->socketdes, (struct sockaddr *)sock->local_addr, &namelen);
+ if (sock->local_addr->sin_port == 0) {
+ /* connect() got us an ephemeral port */
+ sock->local_port_unknown = 1;
+ }
+ if (sock->local_addr->sin_addr.s_addr == 0) {
+ /* not bound to specific local interface; connect() had to assign
+ * one for the socket
+ */
+ sock->local_interface_unknown = 1;
+ }
#ifndef HAVE_POLL
sock->connected=1;
#endif
@@ -240,11 +265,8 @@
(*sock)->addr_len = sizeof(*(*sock)->local_addr);
(*sock)->timeout = -1;
- if (getsockname(*thesock, (struct sockaddr *)(*sock)->local_addr,
- &((*sock)->addr_len)) < 0) {
- return errno;
- }
}
+ (*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
(*sock)->socketdes = *thesock;
return APR_SUCCESS;
}