Quellcode durchsuchen

Change option `tcp_nodelay` from boolean to number

This allows to implement a finer control over when to disable Nagle's algorithm.
See comment on #258
bel vor 9 Jahren
Ursprung
Commit
55eea8eb8d
2 geänderte Dateien mit 30 neuen und 15 gelöschten Zeilen
  1. 8 5
      docs/UserManual.md
  2. 22 10
      src/civetweb.c

+ 8 - 5
docs/UserManual.md

@@ -382,13 +382,16 @@ must be called error404.ext, error4xx.ext or error.ext, whereas the file
 extention may be one of the extentions specified for the index_files option.
 See the [Wikipedia page on HTTP status codes](http://en.wikipedia.org/wiki/HTTP_status_code).
 
-### tcp\_nodelay `no`
-Enable TCP_NODELAY socket option on client connections, either yes or no.
+### tcp\_nodelay `0`
+Enable TCP_NODELAY socket option on client connections.
 
-If set the socket option will disable Nagle's algorithm on the connection 
-which means that packets will be sent as soon as possible instead of waiting 
+If set the socket option will disable Nagle's algorithm on the connection
+which means that packets will be sent as soon as possible instead of waiting
 for a full buffer or timeout to occur.
 
+    0    Keep the default: Nagel's algorithm enabled
+    1    Disable Nagel's algorithm for all sockets
+
 ### decode\_url `yes`
 URL encoded request strings are decoded in the server, unless it is disabled
 by setting this option to `no`.
@@ -415,7 +418,7 @@ than the depth set here connection is refused.
 Loads default trusted certificates locations set at openssl compile time.
 
 ### ssl_cipher_list
-List of ciphers to present to the client. Entries should be separated by 
+List of ciphers to present to the client. Entries should be separated by
 colons, commas or spaces.
 
     ALL           All available ciphers

+ 22 - 10
src/civetweb.c

@@ -1168,7 +1168,7 @@ static struct mg_option config_options[] = {
 #endif
     {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"},
     {"error_pages", CONFIG_TYPE_DIRECTORY, NULL},
-    {"tcp_nodelay", CONFIG_TYPE_BOOLEAN, "no"},
+    {"tcp_nodelay", CONFIG_TYPE_NUMBER, "0"},
 
     {NULL, CONFIG_TYPE_UNKNOWN, NULL}};
 
@@ -10944,6 +10944,22 @@ set_sock_timeout(SOCKET sock, int milliseconds)
 }
 
 
+static int
+set_tcp_nodelay(SOCKET sock, int nodelay_on)
+{
+	if (setsockopt(sock,
+	               IPPROTO_TCP,
+	               TCP_NODELAY,
+	               (SOCK_OPT_TYPE)&nodelay_on,
+	               sizeof(nodelay_on)) != 0) {
+		/* Error */
+		return 1;
+	}
+	/* OK */
+	return 0;
+}
+
+
 static void
 close_socket_gracefully(struct mg_connection *conn)
 {
@@ -12104,9 +12120,8 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		 * keep-alive
 		 * is enabled, and client resets the connection, server won't get
 		 * TCP FIN or RST and will keep the connection open forever. With
-		 * TCP
-		 * keep-alive, next keep-alive handshake will figure out that the
-		 * client is down and will close the server end.
+		 * TCP keep-alive, next keep-alive handshake will figure out that
+		 * the client is down and will close the server end.
 		 * Thanks to Igor Klopov who suggested the patch. */
 		if (setsockopt(so.sock,
 		               SOL_SOCKET,
@@ -12127,12 +12142,9 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		 * persistent connections are used and the responses are relatively
 		 * small (eg. less than 1400 bytes).
 		 */
-		if (ctx && mg_strcasecmp(ctx->config[CONFIG_TCP_NODELAY], "yes") == 0) {
-			if (setsockopt(so.sock,
-			               IPPROTO_TCP,
-			               TCP_NODELAY,
-			               (SOCK_OPT_TYPE)&on,
-			               sizeof(on)) != 0) {
+		if ((ctx != NULL) && (ctx->config[CONFIG_TCP_NODELAY] != NULL)
+		    && (!strcmp(ctx->config[CONFIG_TCP_NODELAY], "1"))) {
+			if (set_tcp_nodelay(so.sock, 1) != 0) {
 				mg_cry(fc(ctx),
 				       "%s: setsockopt(IPPROTO_TCP TCP_NODELAY) failed: %s",
 				       __func__,