Module: sip-router Branch: andrei/raw_sock Commit: 861d3a2edc57842e35768d06ea4440e53a6f2f81 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=861d3a2e...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Wed Jun 9 22:55:21 2010 +0200
core: basic support for receiving udp sip packets on raw sockets
Functions for receiving udp sip packets from raw sockets.
---
raw_listener.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ raw_listener.h | 39 +++++++++++++++ 2 files changed, 186 insertions(+), 0 deletions(-)
diff --git a/raw_listener.c b/raw_listener.c new file mode 100644 index 0000000..ef707a2 --- /dev/null +++ b/raw_listener.c @@ -0,0 +1,147 @@ +/* + * 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. + */ +/** raw socket udp listen functions. + * @file raw_listener.c + * @ingroup core + * Module: @ref core + */ +/* + * History: + * -------- + * 2010-06-09 intial version (from older code) andrei + */ + +#ifdef USE_RAW_SOCKS + +#include "../../config.h" +#include "../../receive.h" + +#include "raw_listener.h" +#include "raw_sock.h" +#include "tlb_send.h" +#include "tlb_cfg.h" + +#include <errno.h> +#include <string.h> + +struct raw_listen_info* raw_sendipv4=0; + +/** creates a raw socket based on a socket_info structure. + * Side-effects: sets raw_udp_sendipv4 if not already set. + * @param si - pointer to partially filled socket_info structure (su must + * be set). + * @param iface - pointer to network interface to bind on (str). Can be null. + * @param iphdr_incl - 1 if send on these socket will include the IP header. + * @return <0 on error, socket on success. + */ +int raw_listener_init(struct socket_info* si, str* iface, int iphdr_incl) +{ + int sock; + struct ip_addr ip; + + su2ip_addr(&ip, &si->su); + sock=raw_udp4_socket(&ip, iface, iphdr_incl); + if (sock>=0){ + if (raw_sendipv4==0 || iface==0 || iface->s==0) + raw_udp_sendipv4=si; + } + return sock; +} + + + +/** receive sip udp ipv4 packets over a raw socket in a loop. + * It should be called by a "raw socket receiver" process + * (since the function never exits unless it encounters a + * critical error). + * @param rsock - initialized raw socket. + * @param port1 - start of port range. + * @param port2 - end of port range. If 0 it's equivalent to listening only + * on port1. + * @return <0 on error, never returns on success. + */ +int raw_udp4_rcv_loop(int rsock, int port1, int port2) +{ + static char buf[BUF_SIZE+1]; + char* p; + char* tmp; + union sockaddr_union from; + union sockaddr_union to; + struct receive_info ri; + struct raw_filter rf; + int len; + + /* this will not change */ + from.sin.sin_family=AF_INET; + ri.bind_address=0; + ri.proto=PROTO_UDP; + ri.proto_reserved1=0; + ri.proto_reserved2=0; + /* set filter to match any address but with the specified port range */ + memset(&rf, 0, sizeof(rf)); + rf.dst.ip.af=AF_INET; + rf.dst.ip.len=4; + rf.dst.mask.af=AF_INET; + rf.dst.mask.len=4; + rf.proto=PROTO_UDP; + rf.port1=port1; + rf.port2=port2?port2:port1; + for(;;){ + p=buf; + len=raw_udp4_recv(rsock, &p, BUF_SIZE, &from, &to, &rf); + if (len<0){ + if (len==-1){ + LOG(L_ERR, "ERROR: raw_udp4_rcv_loop:raw_udp4_recv: %s [%d]\n", + strerror(errno), errno); + if ((errno==EINTR)||(errno==EWOULDBLOCK)) + continue; + else + goto error; + }else{ + DBG("raw_udp4_rcv_loop: raw_udp4_recv error: %d\n", len); + continue; + } + } + /* we must 0-term the message */ + p[len]=0; + ri.src_su=from; + su2ip_addr(&ri.src_ip, &from); + ri.src_port=su_getport(&from); + su2ip_addr(&ri.dst_ip, &to); + ri.dst_port=su_getport(&to); + /* sanity checks */ + if (len<MIN_UDP_PACKET){ + tmp=ip_addr2a(&ri.src_ip); + DBG("raw_udp4_rcv_loop: probing packet received from %s %d\n", + tmp, htons(ri.src_port)); + continue; + } + if (ri.src_port==0){ + tmp=ip_addr2a(&ri.src_ip); + LOG(L_INFO, "raw_udp4_rcv_loop: dropping 0 port packet from %s\n", + tmp); + continue; + } + tmp=ip_addr2a(&ri.src_ip); + DBG("raw_udp4_rcv_loop: received from %s:\n[%.*s]\n", tmp, len, p); + receive_msg(p, len, &ri); + } +error: + return -1; +} + + +#endif /* USE_RAW_SOCKS */ diff --git a/raw_listener.h b/raw_listener.h new file mode 100644 index 0000000..5bc2f58 --- /dev/null +++ b/raw_listener.h @@ -0,0 +1,39 @@ +/* + * 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. + */ +/** raw socket udp listen functions. + * @file raw_listener.h + * @ingroup core + * Module: @ref core + */ +/* + * History: + * -------- + * 2010-06-09 initial version (from older code) andrei + */ + +#ifndef _raw_listener_h +#define _raw_listener_h + +#include "../../ip_addr.h" + + +/** default raw socket used for sending on udp ipv4 */ +struct struct_info* raw_udp_sendipv4; + +int raw_listener_init(struct socket_info* si, str* iface, int iphdr_incl); +int raw_udp4_rcv_loop(int rsock, int port1, int port2); + +#endif /* _raw_listener_h */
2010/6/9 Andrei Pelinescu-Onciul andrei@iptel.org:
core: basic support for receiving udp sip packets on raw sockets
Cool, then we can already receive XCAP over HTTP over UDP over raw sockets... or even better: SIP over ICMP !! :)