|
|
|
@ -1512,6 +1512,8 @@ static void call_destroy(struct call *c) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef int (*csa_func)(char *o, struct peer *p, enum stream_address_format format, int *len); |
|
|
|
|
|
|
|
static int call_stream_address4(char *o, struct peer *p, enum stream_address_format format, int *len) { |
|
|
|
struct callstream *cs = p->up; |
|
|
|
u_int32_t ip4; |
|
|
|
@ -1562,42 +1564,51 @@ static int call_stream_address6(char *o, struct peer *p, enum stream_address_for |
|
|
|
return AF_INET6; |
|
|
|
} |
|
|
|
|
|
|
|
int call_stream_address(char *o, struct peer *p, enum stream_address_format format, int *len) { |
|
|
|
static csa_func __call_stream_address(struct peer *p, int variant) { |
|
|
|
struct callmaster *m; |
|
|
|
struct peer *other; |
|
|
|
csa_func variants[2]; |
|
|
|
|
|
|
|
assert(variant >= 0); |
|
|
|
assert(variant < ARRAYSIZE(variants)); |
|
|
|
|
|
|
|
m = p->up->call->callmaster; |
|
|
|
other = &p->up->peers[p->idx ^ 1]; |
|
|
|
|
|
|
|
variants[0] = call_stream_address4; |
|
|
|
variants[1] = call_stream_address6; |
|
|
|
|
|
|
|
if (is_addr_unspecified(&m->conf.ipv6)) { |
|
|
|
variants[1] = NULL; |
|
|
|
goto done; |
|
|
|
} |
|
|
|
if (other->desired_family == AF_INET) |
|
|
|
return call_stream_address4(o, p, format, len); |
|
|
|
goto done; |
|
|
|
if (other->desired_family == 0 && IN6_IS_ADDR_V4MAPPED(&other->rtps[0].peer.ip46)) |
|
|
|
return call_stream_address4(o, p, format, len); |
|
|
|
goto done; |
|
|
|
if (other->desired_family == 0 && is_addr_unspecified(&other->rtps[0].peer_advertised.ip46)) |
|
|
|
return call_stream_address4(o, p, format, len); |
|
|
|
if (is_addr_unspecified(&m->conf.ipv6)) |
|
|
|
return call_stream_address4(o, p, format, len); |
|
|
|
goto done; |
|
|
|
|
|
|
|
variants[0] = call_stream_address6; |
|
|
|
variants[1] = call_stream_address4; |
|
|
|
goto done; |
|
|
|
|
|
|
|
return call_stream_address6(o, p, format, len); |
|
|
|
done: |
|
|
|
return variants[variant]; |
|
|
|
} |
|
|
|
|
|
|
|
int call_stream_address_alt(char *o, struct peer *p, enum stream_address_format format, int *len) { |
|
|
|
struct callmaster *m; |
|
|
|
struct peer *other; |
|
|
|
int call_stream_address(char *o, struct peer *p, enum stream_address_format format, int *len) { |
|
|
|
csa_func f; |
|
|
|
|
|
|
|
m = p->up->call->callmaster; |
|
|
|
other = &p->up->peers[p->idx ^ 1]; |
|
|
|
f = __call_stream_address(p, 0); |
|
|
|
return f(o, p, format, len); |
|
|
|
} |
|
|
|
|
|
|
|
if (other->desired_family == AF_INET) |
|
|
|
return call_stream_address6(o, p, format, len); |
|
|
|
if (other->desired_family == 0 && IN6_IS_ADDR_V4MAPPED(&other->rtps[0].peer.ip46)) |
|
|
|
return call_stream_address6(o, p, format, len); |
|
|
|
if (other->desired_family == 0 && is_addr_unspecified(&other->rtps[0].peer_advertised.ip46)) |
|
|
|
return call_stream_address6(o, p, format, len); |
|
|
|
if (is_addr_unspecified(&m->conf.ipv6)) |
|
|
|
return call_stream_address6(o, p, format, len); |
|
|
|
int call_stream_address_alt(char *o, struct peer *p, enum stream_address_format format, int *len) { |
|
|
|
csa_func f; |
|
|
|
|
|
|
|
return call_stream_address4(o, p, format, len); |
|
|
|
f = __call_stream_address(p, 1); |
|
|
|
return f ? f(o, p, format, len) : -1; |
|
|
|
} |
|
|
|
|
|
|
|
int callmaster_has_ipv6(struct callmaster *m) { |
|
|
|
|