Hi
Some of my callweaver insallations are in a network where I have several
Gateway-Interfaces. There I'm routing VoIP based on the tos settings. As
we can set tos-values for packets generated by callweaver this is
working quite well.
However Callweaver is using the wrong address in the headers of the
sip-messages. I've changed the cw_ouraddrfor function a little bit to
set the tos-value (if non zero) so that the kernel can report even the
correct ip-address for outgoing traffic when there are special routing
rules for tos values.
I've tested my changes on linux and it seems to do what I want.
Unfortunatelly this isn't working when using iptables to mark packets
based on tos values as the routing stack on linux is setting the src ip
BEFORE iptables OUTGOING rules can set the marks and though before
fwmark rules set with iproute2 apply. (This is why we need to use the
SNAT or MASQUERADE rules to set the correct ip).
My tested settings:
tos=28 in callweaver
ip rule add tos 0x1c lookup 15 (table 15 is a special routing table in
my environement => traffic goes to a separate vlan)
Result: Callweaver isn't using the correct ip before patching callweaver
but is using the correct ip after applying my patch.
By the way: I've searched for a possibility to open a ticket but didn't
find a way to? Do I need to register somewhere to open tickets?
Regards,
Pirmin
diff -r -u callweaver-RC-1.1.99.20090413/channels/chan_mgcp.c callweaver-toschange/channels/chan_mgcp.c
--- callweaver-RC-1.1.99.20090413/channels/chan_mgcp.c 2008-07-30 23:40:03.000000000 +0200
+++ callweaver-toschange/channels/chan_mgcp.c 2009-04-23 09:56:11.000000000 +0200
@@ -1576,7 +1576,7 @@
if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) ||
(g->addr.sin_port != sin->sin_port)) {
memcpy(&g->addr, sin, sizeof(g->addr));
- if (cw_ouraddrfor(&g->addr.sin_addr, &g->ourip))
+ if (cw_ouraddrfor(&g->addr.sin_addr, &g->ourip, tos))
memcpy(&g->ourip, &__ourip, sizeof(g->ourip));
if (option_verbose > 2)
cw_verbose(VERBOSE_PREFIX_3 "Registered MGCP gateway '%s' at %s port %d\n", g->name, cw_inet_ntoa(iabuf, sizeof(iabuf), g->addr.sin_addr), ntohs(g->addr.sin_port));
@@ -3925,7 +3925,7 @@
if (gw->addr.sin_addr.s_addr && !ntohs(gw->addr.sin_port))
gw->addr.sin_port = htons(DEFAULT_MGCP_GW_PORT);
if (gw->addr.sin_addr.s_addr)
- if (cw_ouraddrfor(&gw->addr.sin_addr, &gw->ourip))
+ if (cw_ouraddrfor(&gw->addr.sin_addr, &gw->ourip, tos))
memcpy(&gw->ourip, &__ourip, sizeof(gw->ourip));
return (gw_reload ? NULL : gw);
diff -r -u callweaver-RC-1.1.99.20090413/channels/chan_sip.c callweaver-toschange/channels/chan_sip.c
--- callweaver-RC-1.1.99.20090413/channels/chan_sip.c 2009-04-13 23:40:02.000000000 +0200
+++ callweaver-toschange/channels/chan_sip.c 2009-04-23 09:55:40.000000000 +0200
@@ -1579,7 +1579,7 @@
else if (bindaddr.sin_addr.s_addr) {
memcpy(us, &bindaddr.sin_addr, sizeof(struct in_addr));
} else {
- res=cw_ouraddrfor(them, us);
+ res=cw_ouraddrfor(them, us, tos);
if (option_debug > 5 )
cw_log(LOG_DEBUG, "cw_sip_ouraddrfor debug (no stun) %d\n",res);
}
diff -r -u callweaver-RC-1.1.99.20090413/channels/sccp/sccp_socket.c callweaver-toschange/channels/sccp/sccp_socket.c
--- callweaver-RC-1.1.99.20090413/channels/sccp/sccp_socket.c 2008-05-20 01:40:04.000000000 +0200
+++ callweaver-toschange/channels/sccp/sccp_socket.c 2009-04-23 09:56:43.000000000 +0200
@@ -190,7 +190,7 @@
sccp_log(1)(VERBOSE_PREFIX_3 "SCCP: Accepted connection from %s\n", cw_inet_ntoa(iabuf, sizeof(iabuf), s->sin.sin_addr));
if (GLOB(bindaddr.sin_addr.s_addr) == INADDR_ANY) {
- cw_ouraddrfor(&incoming.sin_addr, &s->ourip);
+ cw_ouraddrfor(&incoming.sin_addr, &s->ourip, GLOB(tos));
} else {
memcpy(&s->ourip, &GLOB(bindaddr.sin_addr.s_addr), sizeof(s->ourip));
}
diff -r -u callweaver-RC-1.1.99.20090413/corelib/acl.c callweaver-toschange/corelib/acl.c
--- callweaver-RC-1.1.99.20090413/corelib/acl.c 2008-05-20 01:40:04.000000000 +0200
+++ callweaver-toschange/corelib/acl.c 2009-04-23 10:25:53.000000000 +0200
@@ -302,7 +302,7 @@
}
}
-int cw_ouraddrfor(struct in_addr *them, struct in_addr *us)
+int cw_ouraddrfor(struct in_addr *them, struct in_addr *us, int tos)
{
int s;
struct sockaddr_in sin;
@@ -313,6 +313,9 @@
cw_log(LOG_WARNING, "Cannot create socket\n");
return -1;
}
+ if (tos>0)
+ setsockopt(s, IPPROTO_IP, IP_TOS, (int *)&tos, sizeof(tos));
+
sin.sin_family = AF_INET;
sin.sin_port = 5060;
sin.sin_addr = *them;
@@ -355,7 +358,7 @@
}
}
/* A.ROOT-SERVERS.NET. */
- if (inet_aton("198.41.0.4", &saddr) && !cw_ouraddrfor(&saddr, ourip))
+ if (inet_aton("198.41.0.4", &saddr) && !cw_ouraddrfor(&saddr, ourip, 0))
return 0;
return -1;
}
diff -r -u callweaver-RC-1.1.99.20090413/include/callweaver/acl.h callweaver-toschange/include/callweaver/acl.h
--- callweaver-RC-1.1.99.20090413/include/callweaver/acl.h 2008-05-20 01:40:07.000000000 +0200
+++ callweaver-toschange/include/callweaver/acl.h 2009-04-23 10:16:52.000000000 +0200
@@ -43,7 +43,7 @@
extern int cw_apply_ha(struct cw_ha *ha, struct sockaddr_in *sin);
extern int cw_get_ip(struct sockaddr_in *sin, const char *value);
extern int cw_get_ip_or_srv(struct sockaddr_in *sin, const char *value, const char *service);
-extern int cw_ouraddrfor(struct in_addr *them, struct in_addr *us);
+extern int cw_ouraddrfor(struct in_addr *them, struct in_addr *us, int tos);
extern int cw_lookup_iface(char *iface, struct in_addr *address);
extern struct cw_ha *cw_duplicate_ha_list(struct cw_ha *original);
extern int cw_find_ourip(struct in_addr *ourip, struct sockaddr_in bindaddr);
_______________________________________________
Callweaver-dev mailing list
[email protected]
http://lists.callweaver.org/mailman/listinfo/callweaver-dev