configurable per-call TOS value

pull/11/head
Richard Fuchs 12 years ago
parent 2e9ae75fb0
commit e381e107ec

@ -351,7 +351,7 @@ void kernelize(struct packet_stream *stream) {
mutex_lock(&sink->out_lock);
mpt.target_port = stream->sfd->fd.localport;
mpt.tos = cm->conf.tos;
mpt.tos = call->tos;
mpt.rtcp_mux = MEDIA_ISSET(stream->media, RTCP_MUX);
mpt.dtls = MEDIA_ISSET(stream->media, DTLS);
mpt.stun = PS_ISSET(stream, STUN);
@ -1184,10 +1184,21 @@ fail:
static int get_port6(struct udp_fd *r, u_int16_t p, struct callmaster *m) {
static void __set_tos(int fd, const struct call *c) {
int tos;
setsockopt(fd, IPPROTO_IP, IP_TOS, &c->tos, sizeof(c->tos));
#ifdef IPV6_TCLASS
tos = c->tos;
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos));
#else
#warning "Will not set IPv6 traffic class"
#endif
}
static int get_port6(struct udp_fd *r, u_int16_t p, const struct call *c) {
int fd;
struct sockaddr_in6 sin;
int tos;
fd = socket(AF_INET6, SOCK_DGRAM, 0);
if (fd < 0)
@ -1196,15 +1207,7 @@ static int get_port6(struct udp_fd *r, u_int16_t p, struct callmaster *m) {
nonblock(fd);
reuseaddr(fd);
ipv6only(fd, 0);
if (m->conf.tos)
setsockopt(fd, IPPROTO_IP, IP_TOS, &m->conf.tos, sizeof(m->conf.tos));
#ifdef IPV6_TCLASS
tos = m->conf.tos;
if (tos)
setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos));
#else
#warning "Will not set IPv6 traffic class"
#endif
__set_tos(fd, c);
ZERO(sin);
sin.sin6_family = AF_INET6;
@ -1221,8 +1224,9 @@ fail:
return -1;
}
static int get_port(struct udp_fd *r, u_int16_t p, struct callmaster *m) {
static int get_port(struct udp_fd *r, u_int16_t p, const struct call *c) {
int ret;
struct callmaster *m = c->callmaster;
assert(r->fd == -1);
@ -1234,7 +1238,7 @@ static int get_port(struct udp_fd *r, u_int16_t p, struct callmaster *m) {
bit_array_set(m->ports_used, p);
mutex_unlock(&m->portlock);
ret = get_port6(r, p, m);
ret = get_port6(r, p, c);
if (ret) {
mutex_lock(&m->portlock);
@ -1259,7 +1263,7 @@ static void release_port(struct udp_fd *r, struct callmaster *m) {
r->localport = 0;
}
int __get_consecutive_ports(struct udp_fd *array, int array_len, int wanted_start_port, struct call *c) {
int __get_consecutive_ports(struct udp_fd *array, int array_len, int wanted_start_port, const struct call *c) {
int i, j, cycle = 0;
struct udp_fd *it;
u_int16_t port;
@ -1292,7 +1296,7 @@ int __get_consecutive_ports(struct udp_fd *array, int array_len, int wanted_star
goto release_restart;
}
if (get_port(it, port++, m))
if (get_port(it, port++, c))
goto release_restart;
}
break;
@ -1805,6 +1809,37 @@ static void __unverify_fingerprint(struct call_media *m) {
}
}
static void __set_all_tos(struct call *c) {
GSList *l;
struct stream_fd *sfd;
for (l = c->stream_fds; l; l = l->next) {
sfd = l->data;
__set_tos(sfd->fd.fd, c);
}
}
static void __tos_change(struct call *call, const struct sdp_ng_flags *flags) {
unsigned char new_tos;
/* Handle TOS= parameter. Negative value = no change, not present or too large =
* revert to default, otherwise set specified value. We only do it in an offer, but
* then for both directions. */
if (flags->opmode != OP_OFFER || flags->tos < 0)
return;
if (flags->tos > 255)
new_tos = call->callmaster->conf.default_tos;
else
new_tos = flags->tos;
if (new_tos == call->tos)
return;
call->tos = new_tos;
__set_all_tos(call);
}
/* called with call->master_lock held in W */
int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
const struct sdp_ng_flags *flags)
@ -1823,6 +1858,8 @@ int monologue_offer_answer(struct call_monologue *monologue, GQueue *streams,
if (!other_ml)
return -1;
__tos_change(monologue->call, flags);
ml_media = other_ml_media = NULL;
for (media_iter = streams->head; media_iter; media_iter = media_iter->next) {
@ -2219,6 +2256,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) {
call_str_cpy(c, &c->callid, callid);
c->created = poller_now;
c->dtls_cert = dtls_cert();
c->tos = m->conf.default_tos;
return c;
}

@ -298,6 +298,7 @@ struct call {
str callid;
time_t created;
time_t last_signal;
unsigned char tos;
};
struct callmaster_config {
@ -313,7 +314,7 @@ struct callmaster_config {
unsigned int silent_timeout;
struct redis *redis;
char *b2b_url;
unsigned char tos;
unsigned char default_tos;
};
struct callmaster {
@ -373,7 +374,7 @@ void calls_dump_redis(struct callmaster *);
struct call_monologue *__monologue_create(struct call *call);
void __monologue_tag(struct call_monologue *ml, const str *tag);
struct stream_fd *__stream_fd_new(struct udp_fd *fd, struct call *call);
int __get_consecutive_ports(struct udp_fd *array, int array_len, int wanted_start_port, struct call *c);
int __get_consecutive_ports(struct udp_fd *array, int array_len, int wanted_start_port, const struct call *c);
struct packet_stream *__packet_stream_new(struct call *call);

@ -541,6 +541,7 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu
bencode_get_alt(input, "media-address", "media address", &out->media_address);
if (bencode_get_alt(input, "address-family", "address family", &out->address_family_str))
out->address_family = address_family(&out->address_family_str);
out->tos = bencode_dictionary_get_integer(input, "TOS", 256);
}
static const char *call_offer_answer_ng(bencode_item_t *input, struct callmaster *m,

@ -251,7 +251,7 @@ static void options(int *argc, char ***argv) {
{ "listen-tcp", 'l', 0, G_OPTION_ARG_STRING, &listenps, "TCP port to listen on", "[IP:]PORT" },
{ "listen-udp", 'u', 0, G_OPTION_ARG_STRING, &listenudps, "UDP port to listen on", "[IP46:]PORT" },
{ "listen-ng", 'n', 0, G_OPTION_ARG_STRING, &listenngs, "UDP port to listen on, NG protocol", "[IP46:]PORT" },
{ "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "TOS value to set on streams", "INT" },
{ "tos", 'T', 0, G_OPTION_ARG_INT, &tos, "Default TOS value to set on streams", "INT" },
{ "timeout", 'o', 0, G_OPTION_ARG_INT, &timeout, "RTP timeout", "SECS" },
{ "silent-timeout",'s',0,G_OPTION_ARG_INT, &silent_timeout,"RTP timeout for muted", "SECS" },
{ "pidfile", 'p', 0, G_OPTION_ARG_STRING, &pidfile, "Write PID to file", "FILE" },
@ -476,7 +476,7 @@ no_kernel:
mc.port_max = port_max;
mc.timeout = timeout;
mc.silent_timeout = silent_timeout;
mc.tos = tos;
mc.default_tos = tos;
mc.b2b_url = b2b_url;
ct = NULL;

@ -18,6 +18,7 @@ struct sdp_ng_flags {
struct in6_addr parsed_media_address;
enum stream_direction directions[2];
int address_family;
int tos;
int asymmetric:1,
trust_address:1,
replace_origin:1,

Loading…
Cancel
Save