Skip to content

TCP: Source address is from routing table not from -i flag #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hamzasheikh opened this issue Aug 6, 2014 · 9 comments
Closed

TCP: Source address is from routing table not from -i flag #83

hamzasheikh opened this issue Aug 6, 2014 · 9 comments

Comments

@hamzasheikh
Copy link

Short Description

When using "-t tn" and "-i myip" the IP used to send messages is not myip but the IP from the OS (Linux) routing table.

Also filed the same bug on SourceForge: Issue 147. Posted on mailing list as well.

Steps to Reproduce

On the "server" side start netcat

nc -v -l 10.10.0.55 5060

On the "client" side run built-in UAC scenario using -t tn and -i myip

sipp -sn uac -i 10.10.0.5 -t tn -p 5060 -m 1 -r 1 -trace_msg -message_file run.msg -trace_stat -stf run.stat -trace_err -trace_screen -error_file run.err -send_timeout 5000 -recv_timeout 5000 10.10.0.55

On the "server" side you'll see something like this on the output on netcat

Connection from 10.10.0.4 port 5060 [tcp/*] accepted
INVITE sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/TCP 10.10.0.5:5060;branch=z9hG4bK-2202-1-0
From: sipp <sip:[email protected]:5060>;tag=2202SIPpTag001
To: service <sip:[email protected]:5060>
Call-ID: [email protected]
CSeq: 1 INVITE
Contact: sip:[email protected]:5060
Max-Forwards: 70
Subject: Performance Test
Content-Type: application/sdp
Content-Length:   129

v=0
o=user1 53655765 2353687637 IN IP4 10.10.0.5
s=-
c=IN IP4 10.10.0.5
t=0 0
m=audio 6000 RTP/AVP 0
a=rtpmap:0 PCMU/8000

Observed Result

If you look at the first line of the nc output it says the connection is from 10.10.0.4 instead of 10.10.0.5 (the IP we provided with the -i flag).

I have also tried -ci flag with the same result.

If I use -t un flag then the first line of output of nc is "Connection from 10.10.0.5 port 5060 [udp/*] accepted".

Expected Result

The IP 10.10.0.5 should be used whether -t is tn or un when making connections.

Client Environment

aikchar@opensuse:~/sipp/run> ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:01:c5:95 brd ff:ff:ff:ff:ff:ff
    inet 10.145.194.238/18 brd 10.145.255.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe01:c595/64 scope link 
       valid_lft forever preferred_lft forever
3: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:01:c5:96 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.4/22 brd 10.10.3.255 scope global ens33
       valid_lft forever preferred_lft forever
    inet 10.10.0.5/22 brd 10.10.3.255 scope global secondary ens33:add1
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe01:c596/64 scope link 
       valid_lft forever preferred_lft forever
4: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:50:56:01:c5:97 brd ff:ff:ff:ff:ff:ff
    inet 10.20.0.4/22 brd 10.20.3.255 scope global ens34
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe01:c597/64 scope link 
       valid_lft forever preferred_lft forever

aikchar@opensuse:~/sipp/run> ip r s
default via 10.145.255.254 dev ens32 
10.10.0.0/22 dev ens33  proto kernel  scope link  src 10.10.0.4 
10.20.0.0/22 dev ens34  proto kernel  scope link  src 10.20.0.4 
10.145.192.0/18 dev ens32  proto kernel  scope link  src 10.145.194.238 
127.0.0.0/8 dev lo  scope link

Server Environment

[aikchar@centos ~]$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:50:56:01:c3:96 brd ff:ff:ff:ff:ff:ff
    inet 10.145.194.226/18 brd 10.145.255.255 scope global eth0
    inet6 fe80::250:56ff:fe01:c396/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:50:56:01:c3:97 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.2/22 brd 10.10.3.255 scope global eth1
    inet 10.10.0.51/22 scope global secondary eth1:1
    inet 10.10.0.52/22 scope global secondary eth1:2
    inet 10.10.0.53/22 scope global secondary eth1:3
    inet 10.10.0.54/22 scope global secondary eth1:4
    inet 10.10.0.55/22 scope global secondary eth1:5
    inet 10.10.0.56/22 scope global secondary eth1:6
    inet 10.10.0.57/22 scope global secondary eth1:7
    inet 10.10.0.58/22 scope global secondary eth1:8
    inet 10.10.0.59/22 scope global secondary eth1:9
    inet 10.10.0.60/22 scope global secondary eth1:10
    inet 10.10.0.61/22 scope global secondary eth1:11
    inet 10.10.0.62/22 scope global secondary eth1:12
    inet 10.10.0.63/22 scope global secondary eth1:13
    inet 10.10.0.64/22 scope global secondary eth1:14
    inet 10.10.0.65/22 scope global secondary eth1:15
    inet 10.10.0.66/22 scope global secondary eth1:16
    inet 10.10.0.67/22 scope global secondary eth1:17
    inet 10.10.0.68/22 scope global secondary eth1:18
    inet 10.10.0.69/22 scope global secondary eth1:19
    inet 10.10.0.70/22 scope global secondary eth1:20
    inet6 2002::10:10:0:64/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:63/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:62/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:61/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:60/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5f/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5e/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5d/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5c/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5b/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:5a/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:59/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:58/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:57/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:56/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:55/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:54/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:53/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:52/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 2002::10:10:0:51/96 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::250:56ff:fe01:c397/64 scope link 
       valid_lft forever preferred_lft forever
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:50:56:01:c3:98 brd ff:ff:ff:ff:ff:ff
5: ip6tnl0: <NOARP> mtu 1460 qdisc noop 
    link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

[aikchar@centos ~]$ ip r s
10.10.0.0/22 dev eth1  proto kernel  scope link  src 10.10.0.2 
10.20.0.0/22 via 10.10.0.1 dev eth1 
10.145.192.0/18 dev eth0  proto kernel  scope link  src 10.145.194.226 
169.254.0.0/16 dev eth0  scope link  metric 1002 
169.254.0.0/16 dev eth1  scope link  metric 1003 
169.254.0.0/16 dev eth2  scope link  metric 1004 
default via 10.145.255.254 dev eth0

SIPp Version

The version of SIPp tried:

aikchar@opensuse:~/sipp/run> sipp -v
SIPp v3.3-TLS-SCTP-PCAP, built Jun 23 2013, 00:25:41.
...

Workaround

A workaround I found was to add a SNAT rule to iptables to re-write the IP address. You may need to change the values according to your environment.

iptables -t nat -A POSTROUTING -o eth0 -p tcp ! --sport 5060 -d 192.168.1.21 --dport 5060 -j SNAT --to-source 192.168.1.15

You can delete this rule when not needed.

iptables -t nat -D POSTROUTING -o eth0 -p tcp ! --sport 5060 -d 192.168.1.21 --dport 5060 -j SNAT --to-source 192.168.1.15
wdoekes added a commit that referenced this issue Aug 6, 2014
Reported by Hamza Sheikh, in #83.
@wdoekes
Copy link
Member

wdoekes commented Aug 6, 2014

@hamzasheikh
Copy link
Author

Result

With this fix SIPp sends traffic using the IP address specified with the -i flag for both TCP and UDP. I confirmed it using Wireshark with the v3.3 binary and my private binary (with this fix).

Issue Observed

I saw one issue when using -t tn versus -t t1 and -t un versus -t u1.

 sipp -i 10.10.0.62 10.20.0.55 -t tn -p 5060 -inf /tmp/cs1_10-10-0-52_15068.inf.csv -trace_msg -message_file /tmp/cs1_10-10-0-52_15068.msg -trace_stat -stf /tmp/cs1_10-10-0-52_15068.stat.csv -trace_err -trace_screen -error_file /tmp/cs1_10-10-0-52_15068.err -r 1 -send_timeout 5000 -recv_timeout 5000 -m 1

Using -t tn or -t un caused SIPp to fail to start with the following message when using the binary I compiled from the source code with this fix. SIPp started just fine using the v3.3 binary I was previously using.

2014-08-06 15:19:48.351460 1407363588.351460: Maximum number of open sockets (50000) should be less than the maximum number of open files (1024). Tune this with the ulimit command or the -max_socket option.

With both v3.3 and my private binary, SIPp ran fine with -t t1 or -t u1, as below:

 sipp -i 10.10.0.62 10.20.0.55 -t t1 -p 5060 -inf /tmp/cs1_10-10-0-52_15068.inf.csv -trace_msg -message_file /tmp/cs1_10-10-0-52_15068.msg -trace_stat -stf /tmp/cs1_10-10-0-52_15068.stat.csv -trace_err -trace_screen -error_file /tmp/cs1_10-10-0-52_15068.err -r 1 -send_timeout 5000 -recv_timeout 5000 -m 1

Compile Problems

I was compiling the source with the fix for this issue on CentOS 6.4 (64-bit) as well as CentOS 5.10 (32-bit) and ran into two problems.

I am not experienced enough with C and compiling to know what effect my workarounds had. Maybe they contributed to the issue I observed with -t tn; I can't say for sure.

Problem 1

During ./configure I got the following error:

./configure: line 10602: syntax error near unexpected token AX_CONFIG_FEATURE_ENABLE' ./configure: line 10602: AX_HAVE_EPOLL(AX_CONFIG_FEATURE_ENABLE(epoll),'

I made the error go away by commenting out the offending lines and replacing them with:

HAVE_EPOLL_TRUE=
HAVE_EPOLL_FALSE='#'

Problem 2

During make I got the following errors.

src/sipp-time.o: In function getmicroseconds()': /chroot/root/sipp/src/time.cpp:57: undefined reference toclock_gettime'

I got rid of them by running ./configure and make this way:

LDFLAGS=" -lrt "  ./configure --with-openssl --with-pcap --with-sctp --with-rtpstream
LDFLAGS=" -lrt "  make

Thank You

Thank you for looking into this issue and providing a fix so quickly. Looking forward to getting this fix in the next release so my team and I can upgrade to it on all our setups.

@wdoekes
Copy link
Member

wdoekes commented Aug 7, 2014

The maximum number of open sockets error you saw was because of this commit: 84d01c8 (Sat Feb 1 23:56:51 2014 +0000, new in 3.4)
You get the same error for both -t un and -t tn, unless you decrease -max_socket.

It's not a bug but a feature.

@wdoekes
Copy link
Member

wdoekes commented Aug 7, 2014

Problem 1: did you run aclocal and friends? Of a different version? There is no line 10602 in the supplied configure. You should generally run build.sh, which touches the supplied files so you don't need to rebuild configure.

wdoekes added a commit that referenced this issue Aug 7, 2014
Reported by Hamza Sheikh in #83.
@wdoekes
Copy link
Member

wdoekes commented Aug 7, 2014

Problem 2: fixed in 544abe4.

Thanks for the detailed reports.

@wdoekes
Copy link
Member

wdoekes commented Aug 6, 2015

@vodik: f2e4d3e broke this, according to the regression tests:

Testing github-#0083-1: failed
Testing github-#0083-2: unexpected success

Note that the github-#0083-2 success is worth nothing when github-#0083-1 fails.

@wdoekes wdoekes reopened this Aug 6, 2015
@wdoekes
Copy link
Member

wdoekes commented Aug 10, 2015

Possible fix -- which unfortunately breaks other regression tests. This needs better testing facilities:

diff --git a/regress/github-#0083-1/run b/regress/github-#0083-1/run
index 488481a..1ee7991 100755
--- a/regress/github-#0083-1/run
+++ b/regress/github-#0083-1/run
@@ -9,8 +9,10 @@ sleep 1
 sippbg -m 1 -sn uac -i 127.0.3.1 -t t1 -p 5071 127.0.2.1:5070
 kill -9 $pid

+# It'd be best if tcp src was 127.0.3.1:5071, but see github-#98.
 if grep -q '^Connection from 127.0.3.1:' tmp.log; then
     ok
 else
-    fail
+    got=`sed -e '/^Connection from/!d;s/.*from //' tmp.log`
+    fail "expected tcp src 127.0.3.1:*, got $got"
 fi
diff --git a/regress/github-#0083-2/run b/regress/github-#0083-2/run
index 88802ea..c8085c8 100755
--- a/regress/github-#0083-2/run
+++ b/regress/github-#0083-2/run
@@ -12,41 +12,7 @@ kill -9 $pid
 conn_sport=`sed -ne 's/^Connection from.*://p' tmp.log`
 via_sport=`grep ^Via: tmp.log | sed -e 's/.*:\([0-9]*\);.*/\1/'`
 if test $conn_sport = $via_sport; then
-    unexpected_ok
+    ok
 else
-    expected_fail
+    fail "expected $via_port and $conn_port to be equal"
 fi
-
-
-# This is disabled, because it broke github-#0098.
-#
-# From 807a97fc3ef97811c393266ce57ff8c5afd185d9 Mon Sep 17 00:00:00 2001
-# From: Walter Doekes <[email protected]>
-# Date: Wed, 6 Aug 2014 09:30:48 +0200
-# Subject: [PATCH] Also update local_port value after binding a TCP socket.
-# 
-# The [local_port] will hold the random port that was bound to.
-# ---
-#  src/socket.cpp | 3 +--
-#  1 file changed, 1 insertion(+), 2 deletions(-)
-# 
-# diff --git a/src/socket.cpp b/src/socket.cpp
-# index 9214a2d..74c77b6 100644
-# --- a/src/socket.cpp
-# +++ b/src/socket.cpp
-# @@ -1520,14 +1520,13 @@ int sipp_do_connect_socket(struct sipp_socket *socket)
-#  
-#      if (socket->ss_transport == T_TCP || socket->ss_transport == T_TLS) {
-#          struct sockaddr_storage local_without_port;
-# -        int port = -1;
-#          memcpy(&local_without_port, &local_sockaddr, sizeof(struct sockaddr_storage));
-#          if (local_ip_is_ipv6) {
-#              (_RCAST(struct sockaddr_in6 *, &local_without_port))->sin6_port = htons(0);
-#          } else {
-#              (_RCAST(struct sockaddr_in *, &local_without_port))->sin_port = htons(0);
-#          }
-# -        sipp_bind_socket(socket, &local_without_port, &port);
-# +        sipp_bind_socket(socket, &local_without_port, &local_port);
-#      }
-#  #ifdef USE_SCTP
-#      if (socket->ss_transport == T_SCTP) {
diff --git a/src/socket.cpp b/src/socket.cpp
index e3004c5..3fb276c 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -2515,7 +2515,7 @@ int open_connections()
         memset(&local_sockaddr, 0, sizeof(struct sockaddr_storage));
         local_sockaddr.ss_family = local_addr->ai_addr->sa_family;

-        if (!strlen(local_ip)) {
+        if (local_ip[0] == '\0') {
             get_inet_address(_RCAST(struct sockaddr_storage*, local_addr->ai_addr),
                 local_ip, sizeof(local_ip));
         } else {
@@ -2529,8 +2529,10 @@ int open_connections()
         if (local_sockaddr.ss_family == AF_INET6) {
             local_ip_is_ipv6 = true;
             sprintf(local_ip_escaped, "[%s]", local_ip);
+            inet_pton(AF_INET6, local_ip, &((struct sockaddr_in6*)&local_sockaddr)->sin6_addr);
         } else {
             strcpy(local_ip_escaped, local_ip);
+            inet_pton(AF_INET, local_ip, &((struct sockaddr_in*)&local_sockaddr)->sin_addr);
         }
     }

@@ -2732,10 +2734,14 @@ int open_connections()

             if (tcp_multiplex->ss_ipv6) {
                 struct sockaddr_in6 sa_loc = {AF_INET6};
+                memcpy(&sa_loc.sin6_addr, &((struct sockaddr_in6*)&local_sockaddr)->sin6_addr,
+                       sizeof(struct in6_addr));
                 sa_loc.sin6_port = htons(local_port);
                 sipp_bind_socket(tcp_multiplex, (struct sockaddr_storage*)&sa_loc, NULL);
             } else {
                 struct sockaddr_in sa_loc = {AF_INET};
+                memcpy(&sa_loc.sin_addr, &((struct sockaddr_in*)&local_sockaddr)->sin_addr,
+                       sizeof(struct in_addr));
                 sa_loc.sin_port = htons(local_port);
                 sipp_bind_socket(tcp_multiplex, (struct sockaddr_storage*)&sa_loc, NULL);
             }

@vodik
Copy link
Member

vodik commented Aug 11, 2015

@wdoekes Oh shit, yeah, I just realized that since we don't use the tn/un mode anywhere, I probably only tested that patch against t1/u1... I'll have a look into this tomorrow.

@aksbhati
Copy link

Hi,

I have the patch but I am still seeing that source IP is not the same what has been mentioned with -i option.

Here is what sipp version I have:
sipp -v
SIPp v3.5.0-RTPSTREAM built Jan 20 2017, 04:24:23.

Command I am using is:
sipp -sf callee.xml -i 172.16.80.2 -bind_local 172.16.80.2 172.16.80.11:5060 -inf callee.csv -m 1 -t t1 -p 5070 -trace_msg

Yet message received at remote end is from 172.16.80.1 which I think is what the kernel stack would have picked.

Regards,
Arvind.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants