I finally did a comparison test for Nagle using SMPP. For the test I used a real SMSC with SMPP interface that was accessible through a VPN connection over WAN which represents a common real world case. The SMSC had a throttling limit at 80sms/sec triggered every 10 seconds. I built two versions of Kannel cvs_20090921, one umodified and another one with Nagle disabled and I connected both of them to the same SMSC. The test included the submission of 2000 MTs each containing a 100 character payload with sequential submission (2000 MT to first bearerbox, wait to finish, 2000MT to second bearerbox, wait to finish). The test was repeated 10 times in a time span of eight hours. During the whole process I used tcpdump to calculate the seconds it took for each bearerbox to send the 2000MT pack. The results are presented in the table below (first column Nagle enabled, second column Nagle disabled). The bearerbox configuration for both versions and the patch to disable Nagle are also included. The dumps are not included but I can send them if anyone is interested.

TEST #    |DEFAULT    |NAGLE DISABLED
__________________________________
1    |37        |26
2    |34        |28
3    |43        |24
4    |30        |25
5    |28        |23
6    |35        |24
7    |34        |18
8    |34        |29
9    |39        |33
10    |32        |30
___________________________________
AVERAGE    |34,6        |26
___________________________________
STDEV    |4,32        |4,22



# Core Group Configuration
group = core
# HTTP Admin Interface Configuration
admin-port = 22000
admin-port-ssl = no
admin-password = sms-admin
admin-deny-ip = "*.*.*.*"
admin-allow-ip = "127.0.0.1"
# SMSBOX Interface
smsbox-port = 19000
smsbox-port-ssl = no
# SMSBOX & WAPBOX access-list
box-deny-ip = "*.*.*.*"
box-allow-ip = "127.0.0.1"
udp-allow-ip = "127.0.0.1"
#wdp-interface-name = "*"
# BEARERBOX log files
log-file = /var/log/kannel/bearerbox.log
log-level = 1
access-log = /var/log/kannel/bearerboxaccess.log
#unified-prefix = ""
sms-incoming-queue-limit = -1
store-type = spool
store-location = "/var/spool/kannel/"
store-dump-freq = 5
sms-combine-concatenated-mo = no
sms-resend-retry = 15

group = smsbox
bearerbox-host = 127.0.0.1
bearerbox-port = 19000
smsbox-id = "BOX"
sendsms-port = 11000
sendsms-port-ssl = no
sendsms-chars = "0123456789 +"
log-file = /var/log/kannel/smsbox.log
log-level = 2
access-log = /var/log/kannel/smsboxaccess.log
reply-couldnotfetch = "Sorry no content"
reply-couldnotrepresent = "Sorry invalid content"
reply-requestfailed = "Sorry service failed"
reply-emptymessage = ""
http-request-retry = 50
http-queue-delay = 30
mo-recode = yes

group = smsbox-route
smsbox-id = "BOX"
smsc-id = "cell"

group = sendsms-user
username = "user"
password = "password"
concatenation = yes
max-messages = 3
omit-empty = yes
user-deny-ip = "*.*.*.*"
user-allow-ip = "127.0.0.1"

group = smsc
smsc = smpp
smsc-id = "cell"
host = XXX.XXX.XXX.XXX
port = XXXXX
transceiver-mode = yes
smsc-username = "user"
smsc-password = "password"
system-type = ""
interface-version = 34
address-range = ""
connection-timeout = 60
enquire-link-interval = 30
reconnect-delay = 30
source-addr-ton = 0
source-addr-npi = 1
dest-addr-ton = 0
dest-addr-npi = 1
allowed-smsc-id = "cell"
max-pending-submits = 100


-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Stipe Tolj
Sent: Wednesday, February 25, 2009 5:40 PM
Cc: [email protected]
Subject: Re: Disable Nagle (enable TCP_NODELAY) ?



Michael Zervakis schrieb:


> Hello,

>

> Has anyone ever tried to disable Nagle at Kannel? I'm experiencing TCP

> latency with some connections and I'm suspecting Nagle has to do with it.



didn't try so far. You could patch the relevant source part for the setsockopt()

call and try.



We'd appreciate seeing test results. ;)



Stipe



--

-------------------------------------------------------------------

Kölner Landstrasse 419

40589 Düsseldorf, NRW, Germany



tolj.org system architecture      Kannel Software Foundation (KSF)

http://www.tolj.org/              http://www.kannel.org/



mailto:st_{at}_tolj.org           mailto:stolj_{at}_kannel.org

-------------------------------------------------------------------




--- gwlib/socket.c.orig 2009-09-21 11:37:20.000000000 +0300
+++ gwlib/socket.c      2009-09-24 19:26:43.000000000 +0300
@@ -68,6 +68,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <sys/utsname.h>
@@ -94,7 +95,7 @@
 {
     struct sockaddr_in addr;
     int s;
-    int reuse;
+    int reuse, iTcpNoDelay;
     struct hostent hostinfo;
     char *buff = NULL;
 
@@ -120,7 +121,14 @@
     reuse = 1;
     if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse,
                    sizeof(reuse)) == -1) {
-        error(errno, "setsockopt failed for server address");
+        error(errno, "setsockopt failed for server address socket reuse");
+        goto error;
+    }
+
+    iTcpNoDelay = 1;
+if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &iTcpNoDelay,
+                   sizeof(iTcpNoDelay)) == -1) {
+        error(errno, "setsockopt failed for server address tcp nodelay");
         goto error;
     }
 
@@ -176,7 +184,7 @@
     }
 
     if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") 
!= 0))  {
-        int reuse;
+        int reuse, iTcpNoDelay;
 
         o_addr = empty_sockaddr_in;
         o_addr.sin_family = AF_INET;
@@ -193,7 +201,12 @@
 
         reuse = 1;
         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, 
sizeof(reuse)) == -1) {
-            error(errno, "setsockopt failed before bind");
+            error(errno, "setsockopt failed before bind for socket reuse");
+            goto error;
+        }
+        iTcpNoDelay = 1;
+        if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &iTcpNoDelay, 
sizeof(iTcpNoDelay)) == -1) {
+            error(errno, "setsockopt failed before bind for tcp nodelay");
             goto error;
         }
         if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {
@@ -267,7 +280,7 @@
     }
 
     if (our_port > 0 || (interface_name != NULL && strcmp(interface_name, "*") 
!= 0)) {
-        int reuse;
+        int reuse, iTcpNoDelay;
 
         o_addr = empty_sockaddr_in;
         o_addr.sin_family = AF_INET;
@@ -284,7 +297,12 @@
 
         reuse = 1;
         if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, 
sizeof(reuse)) == -1) {
-            error(errno, "setsockopt failed before bind");
+            error(errno, "setsockopt failed before bind for socket reuse");
+            goto error;
+        }
+        iTcpNoDelay = 1;
+        if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &iTcpNoDelay, 
sizeof(iTcpNoDelay)) == -1) {
+            error(errno, "setsockopt failed before bind for tcp nodelay");
             goto error;
         }
         if (bind(s, (struct sockaddr *) &o_addr, sizeof(o_addr)) == -1) {

Reply via email to