Module: sip-router Branch: andrei/raw_sock Commit: 9eb54078fd76b53f27cb57a13ccae9e14e3b5237 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=9eb54078...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Tue Aug 10 11:09:19 2010 +0200
raw sockets: ttl can be set or auto-detected
The IP TTL used when sending on raw sockets can be set using the core.udp4_raw_ttl config variable. By default it is auto-detected on startup (the same IP TTL as the one for the first udp4 socket is used).
---
cfg_core.c | 24 ++++++++++++++++++++ cfg_core.h | 1 + main.c | 16 +++++++++++++ raw_sock.c | 9 +++---- sock_ut.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sock_ut.h | 39 +++++++++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 5 deletions(-)
diff --git a/cfg_core.c b/cfg_core.c index 7f2018c..88f234f 100644 --- a/cfg_core.c +++ b/cfg_core.c @@ -56,6 +56,8 @@ #include "pt.h" #endif #include "msg_translator.h" /* fix_global_req_flags() */ +#include "globals.h" +#include "sock_ut.h" #include "cfg/cfg.h" #include "cfg_core.h"
@@ -113,6 +115,7 @@ struct cfg_group_core default_core_cfg = { 0, /*!< udp_mtu_try_proto -> default disabled */ 0, /**< udp4_raw (disabled by default) */ 1500, /**< udp4_raw_mtu (1500 by default) */ + -1, /**< udp4_raw_ttl (auto detect by default) */ 0, /*!< force_rport */ L_DBG, /*!< memlog */ 1 /*!< mem_summary -flags: 0 off, 1 shm/pkg_status, 2 shm/pkg_sums */ @@ -153,6 +156,24 @@ static int check_raw_sock_support(void* cfg_h, str* gname, str* name,
+static int udp4_raw_ttl_fixup(void* cfg_h, str* gname, str* name, void** val) +{ + int v; + v = (int)(long)(*val); + if (v < 0) { + if (sendipv4) + v = sock_get_ttl(sendipv4->socket); + } + if (v < 0) { + /* some error => use a reasonable default */ + v = 63; + } + *val = (void*)(long)v; + return 0; +} + + + cfg_def_t core_cfg_def[] = { {"debug", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, "debug level"}, @@ -264,6 +285,9 @@ cfg_def_t core_cfg_def[] = { "set the MTU used when using raw sockets for udp sending." " This value will be used when deciding whether or not to fragment" " the packets."}, + {"udp4_raw_ttl", CFG_VAR_INT | CFG_ATOMIC, -1, 255, udp4_raw_ttl_fixup, 0, + "set the IP TTL used when using raw sockets for udp sending." + " -1 will use the same value as for normal udp sockets."}, {"force_rport", CFG_VAR_INT, 0, 1, 0, fix_global_req_flags, "force rport for all the received messages" }, {"memlog", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0, diff --git a/cfg_core.h b/cfg_core.h index 1c4b3e7..df15c05 100644 --- a/cfg_core.h +++ b/cfg_core.h @@ -103,6 +103,7 @@ struct cfg_group_core { int udp_mtu_try_proto; /*!< if packet> udp_mtu, try proto (e.g. TCP) */ int udp4_raw; /* use raw sockets for sending on udp ipv 4 */ int udp4_raw_mtu; /* mtu used when using udp raw socket */ + int udp4_raw_ttl; /* ttl used when using udp raw sockets */ int force_rport; /*!< if set rport will always be forced*/ int memlog; /*!< log level for memory status/summary info */ int mem_summary; /*!< display memory status/summary info on exit */ diff --git a/main.c b/main.c index a90e855..d157a6b 100644 --- a/main.c +++ b/main.c @@ -188,6 +188,7 @@ #include "basex.h" /* init */ #include "pvapi_init.h" /* init */ #include "pv_core.h" /* register core pvars */ +#include "sock_ut.h"
#ifdef DEBUG_DMALLOC #include <dmalloc.h> @@ -1266,6 +1267,13 @@ int main_loop() default_core_cfg.udp4_raw = 1; /* enabled */ DBG("raw socket possible => turning it on\n"); } + if (default_core_cfg.udp4_raw_ttl < 0) { + /* auto-detect */ + default_core_cfg.udp4_raw_ttl = sock_get_ttl(sendipv4->socket); + if (default_core_cfg.udp4_raw_ttl < 0) + /* error, use some default value */ + default_core_cfg.udp4_raw_ttl = 63; + } } #else default_core.cfg.udp4_raw = 0; @@ -1417,6 +1425,14 @@ int main_loop() default_core_cfg.udp4_raw = 1; /* enabled */ DBG("raw socket possible => turning it on\n"); } + if (default_core_cfg.udp4_raw_ttl < 0) { + /* auto-detect */ + default_core_cfg.udp4_raw_ttl = + sock_get_ttl(sendipv4->socket); + if (default_core_cfg.udp4_raw_ttl < 0) + /* error, use some default value */ + default_core_cfg.udp4_raw_ttl = 63; + } } } #else diff --git a/raw_sock.c b/raw_sock.c index 37ac6e5..5c56e18 100644 --- a/raw_sock.c +++ b/raw_sock.c @@ -56,6 +56,8 @@ #include <netinet/udp.h>
#include "raw_sock.h" +#include "cfg/cfg.h" +#include "cfg_core.h"
/** create and return a raw socket. @@ -79,11 +81,8 @@ int raw_socket(int proto, struct ip_addr* ip, str* iface, int iphdr_incl) char* ifname;
sock = socket(PF_INET, SOCK_RAW, proto); - if (sock==-1){ - ERR("raw_socket: socket() failed: %s [%d]\n", - strerror(errno), errno); + if (sock==-1) goto error; - } /* set socket options */ if (iphdr_incl) { t=1; @@ -426,7 +425,7 @@ inline static int mk_ip_hdr(struct ip* iph, struct in_addr* from, iph->ip_len = htons(payload_len); iph->ip_id = 0; iph->ip_off = 0; /* frag.: first 3 bits=flags=0, last 13 bits=offset */ - iph->ip_ttl = 63; /* FIXME: use some configured value */ + iph->ip_ttl = cfg_get(core, core_cfg, udp4_raw_ttl); iph->ip_p = proto; iph->ip_sum = 0; iph->ip_src = *from; diff --git a/sock_ut.c b/sock_ut.c new file mode 100644 index 0000000..3aee2cd --- /dev/null +++ b/sock_ut.c @@ -0,0 +1,71 @@ +/* + * $Id$ + * + * Copyright (C) 2010 iptelorg GmbH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** various socket related functions. + * @file sock_ut.c + * @ingroup: core + */ +/* + * History: + * -------- + * 2010-08-09 initial version (andrei) +*/ + +#include "sock_ut.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <errno.h> +#include <arpa/inet.h> + + +/** get the IP TTL. + * @return ttl on success, < 0 on error + */ +int sock_get_ttl(int sock) +{ + int ioptval; + unsigned int ioptvallen; + + ioptvallen=sizeof(ioptval); + if (getsockopt( sock, IPPROTO_IP, IP_TTL, (void*) &ioptval, + &ioptvallen) == -1 ) + { + return -1; + } + return ioptval; +} + + + +/** set the IP TTL on a socket. + * @return ttl on success, < 0 on error + */ +int sock_set_ttl(int sock, int ttl) +{ + int ioptval; + + if (setsockopt( sock, IPPROTO_IP, IP_TTL, (void*) &ioptval, + sizeof(ioptval)) == -1 ) + return -1; + return ioptval; +} + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/sock_ut.h b/sock_ut.h new file mode 100644 index 0000000..e9613d1 --- /dev/null +++ b/sock_ut.h @@ -0,0 +1,39 @@ +/* + * $Id$ + * + * Copyright (C) 2010 iptelorg GmbH + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** various socket related functions. + * @file sock_ut.h + * @ingroup: core + */ +/* + * History: + * -------- + * 2010-08-09 initial version (andrei) +*/ + +#ifndef __sock_ut_h +#define __sock_ut_h + + + +int sock_get_ttl(int sock); +int sock_set_ttl(int sock, int ttl); + + +#endif /*__sock_ut_h*/ + +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */