trawick 01/04/05 11:56:09
Modified: . CHANGES configure.in
build apr_network.m4
include apr.h.in
include/arch/unix networkio.h
network_io/unix sockets.c sockopt.c
Log:
Recognize systems where the TCP_NODELAY setting is inherited from
the listening socket, and optimize apr_setsockopt(APR_TCP_NODELAY)
accordingly.
Also, note a recent change to find getnameinfo() on Tru64 in
CHANGES.
Revision Changes Path
1.85 +6 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -r1.84 -r1.85
--- CHANGES 2001/04/03 20:32:05 1.84
+++ CHANGES 2001/04/05 18:56:05 1.85
@@ -1,5 +1,11 @@
Changes with APR b1
+ *) Recognize systems where the TCP_NODELAY setting is inherited from
+ the listening socket, and optimize apr_setsockopt(APR_TCP_NODELAY)
+ accordingly. [Jeff Trawick]
+
+ *) Recognize the presence of getnameinfo() on Tru64. [David Reid]
+
*) Allow APR to be installed. [Ryan Bloom]
*) Generate config.nice for easy re-run of configure. [Roy Fielding]
1.277 +4 -0 apr/configure.in
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.276
retrieving revision 1.277
diff -u -r1.276 -r1.277
--- configure.in 2001/04/05 18:08:30 1.276
+++ configure.in 2001/04/05 18:56:05 1.277
@@ -431,6 +431,7 @@
AC_SUBST(fork)
AC_SUBST(have_inet_addr)
+AC_SUBST(tcp_nodelay_inherited)
AC_SUBST(have_inet_network)
AC_SUBST(have_sigaction)
AC_SUBST(have_setrlimit)
@@ -514,6 +515,7 @@
], netinet_tcph="1", netinet_tcph="0")
if test $netinet_tcph = 1; then
AC_MSG_RESULT(yes)
+ echo "#define HAVE_NETINET_TCP_H 1" >> confdefs.h
else
AC_MSG_RESULT(no)
fi
@@ -944,6 +946,8 @@
APR_CHECK_SOCKADDR_SA_LEN
APR_CHECK_GETHOSTBYNAME_NAS
+
+APR_CHECK_TCP_NODELAY_INHERITED
dnl # Look for a way of corking TCP...
APR_CHECK_DEFINE(TCP_CORK, netinet/tcp.h)
1.5 +105 -0 apr/build/apr_network.m4
Index: apr_network.m4
===================================================================
RCS file: /home/cvs/apr/build/apr_network.m4,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apr_network.m4 2001/04/05 18:08:30 1.4
+++ apr_network.m4 2001/04/05 18:56:06 1.5
@@ -146,6 +146,111 @@
])
+dnl
+dnl see if TCP_NODELAY setting is inherited from listening sockets
+dnl
+AC_DEFUN(APR_CHECK_TCP_NODELAY_INHERITED,[
+ AC_CACHE_CHECK(if TCP_NODELAY setting is inherited from listening sockets,
ac_cv_tcp_nodelay_inherited,[
+ AC_TRY_RUN( [
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+int main(void) {
+ int listen_s, connected_s, client_s;
+ int listen_port, rc;
+ struct sockaddr_in sa;
+ int sa_len;
+ int option_len;
+ int option;
+
+ listen_s = socket(AF_INET, SOCK_STREAM, 0);
+ if (listen_s < 0) {
+ perror("socket");
+ exit(1);
+ }
+ option = 1;
+ rc = setsockopt(listen_s, IPPROTO_TCP, TCP_NODELAY, &option, sizeof
option);
+ if (rc < 0) {
+ perror("setsockopt TCP_NODELAY");
+ exit(1);
+ }
+ memset(&sa, 0, sizeof sa);
+ sa.sin_family = AF_INET;
+ /* leave port 0 to get ephemeral */
+ rc = bind(listen_s, (struct sockaddr *)&sa, sizeof sa);
+ if (rc < 0) {
+ perror("bind for ephemeral port");
+ exit(1);
+ }
+ /* find ephemeral port */
+ sa_len = sizeof(sa);
+ rc = getsockname(listen_s, (struct sockaddr *)&sa, &sa_len);
+ if (rc < 0) {
+ perror("getsockname");
+ exit(1);
+ }
+ listen_port = sa.sin_port;
+ rc = listen(listen_s, 5);
+ if (rc < 0) {
+ perror("listen");
+ exit(1);
+ }
+ client_s = socket(AF_INET, SOCK_STREAM, 0);
+ if (client_s < 0) {
+ perror("socket");
+ exit(1);
+ }
+ memset(&sa, 0, sizeof sa);
+ sa.sin_family = AF_INET;
+ sa.sin_port = listen_port;
+ /* leave sin_addr all zeros to use loopback */
+ rc = connect(client_s, (struct sockaddr *)&sa, sizeof sa);
+ if (rc < 0) {
+ perror("connect");
+ exit(1);
+ }
+ sa_len = sizeof sa;
+ connected_s = accept(listen_s, (struct sockaddr *)&sa, &sa_len);
+ if (connected_s < 0) {
+ perror("accept");
+ exit(1);
+ }
+ option_len = sizeof option;
+ rc = getsockopt(connected_s, IPPROTO_TCP, TCP_NODELAY, &option,
&option_len);
+ if (rc < 0) {
+ perror("getsockopt");
+ exit(1);
+ }
+ if (!option) {
+ fprintf(stderr, "TCP_NODELAY is not set in the child.\n");
+ exit(1);
+ }
+ return 0;
+}
+],[
+ ac_cv_tcp_nodelay_inherited="yes"
+],[
+ ac_cv_tcp_nodelay_inherited="no"
+],[
+ ac_cv_tcp_nodelay_inherited="yes"
+])])
+if test "$ac_cv_tcp_nodelay_inherited" = "yes"; then
+ tcp_nodelay_inherited=1
+else
+ tcp_nodelay_inherited=0
+fi
+])
+
dnl
dnl check for socklen_t, fall back to unsigned int
dnl
1.78 +4 -0 apr/include/apr.h.in
Index: apr.h.in
===================================================================
RCS file: /home/cvs/apr/include/apr.h.in,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- apr.h.in 2001/04/03 01:09:49 1.77
+++ apr.h.in 2001/04/05 18:56:07 1.78
@@ -146,6 +146,10 @@
*/
#define APR_TCP_NOPUSH_FLAG @apr_tcp_nopush_flag@
+/* Is the TCP_NODELAY socket option inherited from listening sockets?
+*/
+#define APR_TCP_NODELAY_INHERITED @tcp_nodelay_inherited@
+
/* Typedefs that APR needs. */
typedef unsigned char apr_byte_t;
1.41 +2 -0 apr/include/arch/unix/networkio.h
Index: networkio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/networkio.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- networkio.h 2001/03/31 13:25:45 1.40
+++ networkio.h 2001/04/05 18:56:07 1.41
@@ -156,6 +156,8 @@
const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t
size);
int apr_inet_pton(int af, const char *src, void *dst);
+int apr_is_option_set(apr_int32_t, apr_int32_t);
+void apr_set_option(apr_int32_t *, apr_int32_t, int);
#endif /* ! NETWORK_IO_H */
1.73 +6 -0 apr/network_io/unix/sockets.c
Index: sockets.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sockets.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -r1.72 -r1.73
--- sockets.c 2001/03/31 13:25:45 1.72
+++ sockets.c 2001/04/05 18:56:08 1.73
@@ -230,6 +230,12 @@
(*new)->local_port_unknown = 1;
}
+#if APR_TCP_NODELAY_INHERITED
+ if (apr_is_option_set(sock->netmask, APR_TCP_NODELAY) == 1) {
+ apr_set_option(&(*new)->netmask, APR_TCP_NODELAY, 1);
+ }
+#endif /* TCP_NODELAY_INHERITED */
+
if (sock->local_interface_unknown ||
/* XXX IPv6 issue */
sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
1.45 +29 -29 apr/network_io/unix/sockopt.c
Index: sockopt.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sockopt.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- sockopt.c 2001/04/03 00:43:09 1.44
+++ sockopt.c 2001/04/05 18:56:08 1.45
@@ -55,12 +55,12 @@
#include "networkio.h"
#include "apr_strings.h"
-static int is_option_set(apr_int32_t mask, apr_int32_t option)
+int apr_is_option_set(apr_int32_t mask, apr_int32_t option)
{
return (mask & option) == option;
}
-static void set_option(apr_int32_t *mask, apr_int32_t option, int on)
+void apr_set_option(apr_int32_t *mask, apr_int32_t option, int on)
{
if (on)
*mask |= option;
@@ -134,46 +134,46 @@
one = 0;
if (opt & APR_SO_KEEPALIVE) {
#ifdef SO_KEEPALIVE
- if (on != is_option_set(sock->netmask, APR_SO_KEEPALIVE)){
+ if (on != apr_is_option_set(sock->netmask, APR_SO_KEEPALIVE)){
if (setsockopt(sock->socketdes, SOL_SOCKET, SO_KEEPALIVE, (void
*)&one, sizeof(int)) == -1) {
return errno;
}
- set_option(&sock->netmask,APR_SO_KEEPALIVE, on);
+ apr_set_option(&sock->netmask,APR_SO_KEEPALIVE, on);
}
#else
return APR_ENOTIMPL;
#endif
}
if (opt & APR_SO_DEBUG) {
- if (on != is_option_set(sock->netmask, APR_SO_DEBUG)){
+ if (on != apr_is_option_set(sock->netmask, APR_SO_DEBUG)){
if (setsockopt(sock->socketdes, SOL_SOCKET, SO_DEBUG, (void
*)&one, sizeof(int)) == -1) {
return errno;
}
- set_option(&sock->netmask, APR_SO_DEBUG, on);
+ apr_set_option(&sock->netmask, APR_SO_DEBUG, on);
}
}
if (opt & APR_SO_REUSEADDR) {
- if (on != is_option_set(sock->netmask, APR_SO_REUSEADDR)){
+ if (on != apr_is_option_set(sock->netmask, APR_SO_REUSEADDR)){
if (setsockopt(sock->socketdes, SOL_SOCKET, SO_REUSEADDR, (void
*)&one, sizeof(int)) == -1) {
return errno;
}
- set_option(&sock->netmask, APR_SO_REUSEADDR, on);
+ apr_set_option(&sock->netmask, APR_SO_REUSEADDR, on);
}
}
if (opt & APR_SO_SNDBUF) {
#ifdef SO_SNDBUF
- if (is_option_set(sock->netmask, APR_SO_SNDBUF) != on){
+ if (apr_is_option_set(sock->netmask, APR_SO_SNDBUF) != on){
if (setsockopt(sock->socketdes, SOL_SOCKET, SO_SNDBUF, (void
*)&on, sizeof(int)) == -1) {
return errno;
}
- set_option(&sock->netmask, APR_SO_SNDBUF, on);
+ apr_set_option(&sock->netmask, APR_SO_SNDBUF, on);
}
#else
return APR_ENOTIMPL;
#endif
}
if (opt & APR_SO_NONBLOCK) {
- if (is_option_set(sock->netmask, APR_SO_NONBLOCK) != on){
+ if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) != on){
if (on) {
if ((stat = sononblock(sock->socketdes)) != APR_SUCCESS)
return stat;
@@ -182,19 +182,19 @@
if ((stat = soblock(sock->socketdes)) != APR_SUCCESS)
return stat;
}
- set_option(&sock->netmask, APR_SO_NONBLOCK, on);
+ apr_set_option(&sock->netmask, APR_SO_NONBLOCK, on);
}
}
if (opt & APR_SO_LINGER) {
#ifdef SO_LINGER
- if (is_option_set(sock->netmask, APR_SO_LINGER) != on){
+ if (apr_is_option_set(sock->netmask, APR_SO_LINGER) != on){
struct linger li;
li.l_onoff = on;
li.l_linger = MAX_SECS_TO_LINGER;
if (setsockopt(sock->socketdes, SOL_SOCKET, SO_LINGER, (char *)
&li, sizeof(struct linger)) == -1) {
return errno;
}
- set_option(&sock->netmask, APR_SO_LINGER, on);
+ apr_set_option(&sock->netmask, APR_SO_LINGER, on);
}
#else
return APR_ENOTIMPL;
@@ -203,29 +203,29 @@
if (opt & APR_SO_TIMEOUT) {
/* don't do the fcntl foo more than needed */
if (on >= 0 && sock->timeout < 0){
- if (is_option_set(sock->netmask, APR_SO_NONBLOCK) != 1){
+ if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) != 1){
if ((stat = sononblock(sock->socketdes)) != APR_SUCCESS){
return stat;
}
}
}
else if (on < 0 && sock->timeout >= 0){
- if (is_option_set(sock->netmask, APR_SO_NONBLOCK) != 0){
+ if (apr_is_option_set(sock->netmask, APR_SO_NONBLOCK) != 0){
if ((stat = soblock(sock->socketdes)) != APR_SUCCESS) {
return stat;
}
}
}
sock->timeout = on;
- set_option(&sock->netmask, APR_SO_TIMEOUT, on);
+ apr_set_option(&sock->netmask, APR_SO_TIMEOUT, on);
}
if (opt & APR_TCP_NODELAY) {
#if defined(TCP_NODELAY)
- if (is_option_set(sock->netmask, APR_TCP_NODELAY) != on){
+ if (apr_is_option_set(sock->netmask, APR_TCP_NODELAY) != on){
if (setsockopt(sock->socketdes, IPPROTO_TCP, TCP_NODELAY, (void
*)&on, sizeof(int)) == -1) {
return errno;
}
- set_option(&sock->netmask, APR_TCP_NODELAY, on);
+ apr_set_option(&sock->netmask, APR_TCP_NODELAY, on);
}
#else
/* BeOS pre-BONE has TCP_NODELAY set by default.
@@ -242,10 +242,10 @@
}
if (opt & APR_TCP_NOPUSH){
#if APR_TCP_NOPUSH_FLAG
- if (is_option_set(sock->netmask, APR_TCP_NOPUSH) != on){
+ if (apr_is_option_set(sock->netmask, APR_TCP_NOPUSH) != on){
/* OK we're going to change some settings here... */
/* TCP_NODELAY is mutually exclusive, so do we have it set? */
- if (is_option_set(sock->netmask, APR_TCP_NODELAY) == 1 && on){
+ if (apr_is_option_set(sock->netmask, APR_TCP_NODELAY) == 1 &&
on){
/* If we want to set NOPUSH then if we have the TCP_NODELAY
* flag set we need to switch it off...
*/
@@ -254,25 +254,25 @@
(void*)&tmpflag, sizeof(int)) == -1){
return errno;
}
- set_option(&sock->netmask, APR_RESET_NODELAY, 1);
- set_option(&sock->netmask, APR_TCP_NODELAY, 0);
+ apr_set_option(&sock->netmask, APR_RESET_NODELAY, 1);
+ apr_set_option(&sock->netmask, APR_TCP_NODELAY, 0);
} else if (on){
- set_option(&sock->netmask, APR_RESET_NODELAY, 0);
+ apr_set_option(&sock->netmask, APR_RESET_NODELAY, 0);
}
/* OK, now we can just set the TCP_NOPUSH flag accordingly...*/
if (setsockopt(sock->socketdes, IPPROTO_TCP, APR_TCP_NOPUSH_FLAG,
(void*)&on, sizeof(int)) == -1){
return errno;
}
- set_option(&sock->netmask, APR_TCP_NOPUSH, on);
- if (!on && is_option_set(sock->netmask, APR_RESET_NODELAY)){
+ apr_set_option(&sock->netmask, APR_TCP_NOPUSH, on);
+ if (!on && apr_is_option_set(sock->netmask, APR_RESET_NODELAY)){
int tmpflag = 1;
if (setsockopt(sock->socketdes, IPPROTO_TCP, TCP_NODELAY,
(void*)&tmpflag, sizeof(int)) == -1){
return errno;
}
- set_option(&sock->netmask, APR_RESET_NODELAY,0);
- set_option(&sock->netmask, APR_TCP_NODELAY, 1);
+ apr_set_option(&sock->netmask, APR_RESET_NODELAY,0);
+ apr_set_option(&sock->netmask, APR_TCP_NODELAY, 1);
}
}
#else
@@ -290,7 +290,7 @@
*on = sock->timeout;
break;
default:
- *on = is_option_set(sock->netmask, opt);
+ *on = apr_is_option_set(sock->netmask, opt);
}
return APR_SUCCESS;
}