raw sockets: ttl can be set or auto-detected
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 10 Aug 2010 09:09:19 +0000 (11:09 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Tue, 10 Aug 2010 09:09:19 +0000 (11:09 +0200)
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
cfg_core.h
main.c
raw_sock.c
sock_ut.c [new file with mode: 0644]
sock_ut.h [new file with mode: 0644]

index 7f2018c..88f234f 100644 (file)
@@ -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,
index 1c4b3e7..df15c05 100644 (file)
@@ -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 (file)
--- a/main.c
+++ b/main.c
 #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
index 37ac6e5..5c56e18 100644 (file)
@@ -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 (file)
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 (file)
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: */