|
|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|