nils-ohlmeier / sipsak

SIP swiss army knife
GNU General Public License v2.0
140 stars 37 forks source link

Sipsak making DNS request, even if doesn't need to #91

Open os11k opened 2 years ago

os11k commented 2 years ago

I have Ubuntu 20.04 server with no entry for DNS name in /etc/hosts, so my hostname is my.server.com and /etc/hosts doesn't have record for that. Nevertheless hostnamectl return proper DNS name for server itself and everything works as it should(except sipsak).

So problem is that in this environment when I do sipsak -s sip:127.0.0.1, sipsak makes DNS request to find out what server is behind my.server.com. It is easy to reproduce, just run sipsak with similar config and make tcpdump.

This I believe is not ideal behavior.

sipsak 0.9.7  by Nils Ohlmeier
 Copyright (C) 2002-2004 FhG Fokus
 Copyright (C) 2004-2005 Nils Ohlmeier
 compiled with DEFAULT_TIMEOUT=500, FQDN_SIZE=65, LONG_OPTS, INTERNAL_MD5, TLS_SUPPORT(GNUTLS), SRV_SUPPORT(RULI), STR_CASE_INSENSITIVE, CMP_CASE_INSENSITIVE
nils-ohlmeier commented 2 years ago

Without replicating the problem my guess is that the problem lies in sipsak trying to insert an IP address into the Via header of it's SIP messages. By default it does that by looking at the hostname and then trying to resolve that into an IP address to prevent the receivers of the messages having to do DNS lookups.

There are a couple of ways how to test this theory:

I guess this special setup of having a hostname set which isn't resolvable could be worked around by trying to look at IP address of network interfaces. But honestly that is a lot of work for that use case.

os11k commented 2 years ago

This is SIP option what being sent by sipsak:

image

I still don't understand why it needs to make any dns requests, or am I missing something?

os11k commented 2 years ago

To reproduce, install Ubuntu 20.04, make sure /etc/hosts doesn't have any entry related to hostname(what you typically get in AWS):

root@sipsak-test:/usr/src/sipsak# more /etc/hosts
127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Run latest version of sipsak:

./sipsak -s sip:127.0.0.1

Here is pcap:

sipsak2.zip

I just tried with latest master and issue is reproducible:

root@sipsak-test:/usr/src/sipsak# ./sipsak --version
sipsak 0.9.9-pre  by Nils Ohlmeier
 Copyright (C) 2002-2004 FhG Fokus
 Copyright (C) 2004-2005 Nils Ohlmeier
 compiled with DEFAULT_TIMEOUT=500, FQDN_SIZE=65, RAW_SUPPORT, LONG_OPTS, INTERNAL_MD5, STR_CASE_INSENSITIVE, CMP_CASE_INSENSITIVE
os11k commented 2 years ago

In my test environment I was not able to get 127.0.0.1 in all headers, as in printscreen from above, that is taken from production, but if you follow steps above you will get same result, DNS requst is being made, what is not necessary at all, even if headers contains non-loopback IPs like here:

image

sipsak -s sip:127.0.0.1 -H 127.0.0.1 removes DNS request, but again I would assume that by default we should not do anything unnecessary...

I hate to compare but if we check other projects like https://github.com/pbertera/SIPPing

if we run ./sipping.py -d 127.0.0.1 -p 5060 -S 192.168.1.212 -P 4444 -c 1 -T 1 -q 1

image

We do not get any unwanted DNS requests, I'm very surprised that sipsak needs any DNS requests at all, I never saw anything similar on Kamailio project too...

Would be nice to get understanding why sipsak uses hostnames under the hood by default, that seems unnecessary for me...

nils-ohlmeier commented 2 years ago

In SIP URIs are used in several headers. These URI's need either a DNS name or an IP address. DNS names are rarely used in SIP requests. So we want to use IP addresses instead. I currently see three options to figure out which IP address to put into a SIP request:

For SIPping you appear to provide the host part of the URI's per the -S option as well. What does it do if you don't provide that argument?

Sure their is lots of server software which doesn't use the host name. I guess these programs use the first approach to figure out the local IP address. But comparing a little command line tool maintained by a single person in his little free time with a huge server software maintained by a big community is well...

In other words: if someone provides me with a patch to add support for iterating through the network interface I would happily merge it. Or if someone has another smart idea how to get to the hosts IP address, which I haven't listed above I'm all ears.

os11k commented 2 years ago

Hi,

Thank you a lot for explanation!

Probably worth to add that in my production environment, where we use sipsak with keepalived, keepalived uses it every second and if there is no records in /etc/hosts we see those DNS requests every second, additionally seems at some point sipsak stops acknowledging that it received 200ok, to fix it I found workaround just to add records in /etc/hosts and it do helps.

So that why I'm asking why those DNS requests are necessary.

Seems you are correct all others apps asks user to enter IP, what it should use for socket. With sipsak you decided to not go that road and seems in that cases DNS request is a must.

As far as I use sispsak for connectivity testing(and probably most of sipak users do the same), I do run it on server constantly like every second and having additional unnecessary DNS request sent every second is a bit too much, IMHO.

Probably would be good idea to acknowledge somewhere that sipsak do use DNS request, or maybe even force it to ask from user what IP to use, instead of using DNS.

I will try to collect a bit more details from my production environment where I see that sipsak stops acknowledging receiving of 200OK and I will post more details here...