[raop] Fix possible incorrect address family in SDP

This commit is contained in:
ejurgensen 2017-05-04 19:31:26 +02:00
parent 544791ef59
commit f465f6a77d
3 changed files with 23 additions and 14 deletions

View File

@ -142,10 +142,10 @@ void evrtsp_connection_set_base(struct evrtsp_connection *evcon,
void evrtsp_connection_get_peer(struct evrtsp_connection *evcon, void evrtsp_connection_get_peer(struct evrtsp_connection *evcon,
char **address, u_short *port); char **address, u_short *port);
/** Get the local address and port associated with this connection. */ /** Get the local address, port and family associated with this connection. */
void void
evrtsp_connection_get_local_address(struct evrtsp_connection *evcon, evrtsp_connection_get_local_address(struct evrtsp_connection *evcon,
char **address, u_short *port); char **address, u_short *port, int *family);
/** The connection gets ownership of the request */ /** The connection gets ownership of the request */
int evrtsp_make_request(struct evrtsp_connection *evcon, int evrtsp_make_request(struct evrtsp_connection *evcon,

View File

@ -1300,7 +1300,7 @@ evrtsp_connection_set_closecb(struct evrtsp_connection *evcon,
void void
evrtsp_connection_get_local_address(struct evrtsp_connection *evcon, evrtsp_connection_get_local_address(struct evrtsp_connection *evcon,
char **address, u_short *port) char **address, u_short *port, int *family)
{ {
union { union {
struct sockaddr_storage ss; struct sockaddr_storage ss;
@ -1327,7 +1327,9 @@ evrtsp_connection_get_local_address(struct evrtsp_connection *evcon,
if (!*address) if (!*address)
return; return;
switch (addr.ss.ss_family) *family = addr.ss.ss_family;
switch (*family)
{ {
case AF_INET: case AF_INET:
*port = ntohs(addr.sin.sin_port); *port = ntohs(addr.sin.sin_port);

View File

@ -181,6 +181,7 @@ struct raop_session
char *devname; char *devname;
char *address; char *address;
int family;
int volume; int volume;
uint64_t start_rtptime; uint64_t start_rtptime;
@ -1203,13 +1204,13 @@ raop_check_cseq(struct raop_session *rs, struct evrtsp_request *req)
} }
static int static int
raop_make_sdp(struct raop_session *rs, struct evrtsp_request *req, char *address, uint32_t session_id) raop_make_sdp(struct raop_session *rs, struct evrtsp_request *req, char *address, int family, uint32_t session_id)
{ {
#define SDP_PLD_FMT \ #define SDP_PLD_FMT \
"v=0\r\n" \ "v=0\r\n" \
"o=iTunes %u 0 IN IP4 %s\r\n" \ "o=iTunes %u 0 IN %s %s\r\n" \
"s=iTunes\r\n" \ "s=iTunes\r\n" \
"c=IN IP4 %s\r\n" \ "c=IN %s %s\r\n" \
"t=0 0\r\n" \ "t=0 0\r\n" \
"m=audio 0 RTP/AVP 96\r\n" \ "m=audio 0 RTP/AVP 96\r\n" \
"a=rtpmap:96 AppleLossless\r\n" \ "a=rtpmap:96 AppleLossless\r\n" \
@ -1218,17 +1219,22 @@ raop_make_sdp(struct raop_session *rs, struct evrtsp_request *req, char *address
"a=aesiv:%s\r\n" "a=aesiv:%s\r\n"
#define SDP_PLD_FMT_NO_ENC \ #define SDP_PLD_FMT_NO_ENC \
"v=0\r\n" \ "v=0\r\n" \
"o=iTunes %u 0 IN IP4 %s\r\n" \ "o=iTunes %u 0 IN %s %s\r\n" \
"s=iTunes\r\n" \ "s=iTunes\r\n" \
"c=IN IP4 %s\r\n" \ "c=IN %s %s\r\n" \
"t=0 0\r\n" \ "t=0 0\r\n" \
"m=audio 0 RTP/AVP 96\r\n" \ "m=audio 0 RTP/AVP 96\r\n" \
"a=rtpmap:96 AppleLossless\r\n" \ "a=rtpmap:96 AppleLossless\r\n" \
"a=fmtp:96 %d 0 16 40 10 14 2 255 0 0 44100\r\n" "a=fmtp:96 %d 0 16 40 10 14 2 255 0 0 44100\r\n"
const char *af;
const char *rs_af;
char *p; char *p;
int ret; int ret;
af = (family == AF_INET) ? "IP4" : "IP6";
rs_af = (rs->family == AF_INET) ? "IP4" : "IP6";
p = strchr(rs->address, '%'); p = strchr(rs->address, '%');
if (p) if (p)
*p = '\0'; *p = '\0';
@ -1236,11 +1242,11 @@ raop_make_sdp(struct raop_session *rs, struct evrtsp_request *req, char *address
/* Add SDP payload - but don't add RSA/AES key/iv if no encryption - important for ATV3 update 6.0 */ /* Add SDP payload - but don't add RSA/AES key/iv if no encryption - important for ATV3 update 6.0 */
if (rs->encrypt) if (rs->encrypt)
ret = evbuffer_add_printf(req->output_buffer, SDP_PLD_FMT, ret = evbuffer_add_printf(req->output_buffer, SDP_PLD_FMT,
session_id, address, rs->address, AIRTUNES_V2_PACKET_SAMPLES, session_id, af, address, rs_af, rs->address, AIRTUNES_V2_PACKET_SAMPLES,
raop_aes_key_b64, raop_aes_iv_b64); raop_aes_key_b64, raop_aes_iv_b64);
else else
ret = evbuffer_add_printf(req->output_buffer, SDP_PLD_FMT_NO_ENC, ret = evbuffer_add_printf(req->output_buffer, SDP_PLD_FMT_NO_ENC,
session_id, address, rs->address, AIRTUNES_V2_PACKET_SAMPLES); session_id, af, address, rs_af, rs->address, AIRTUNES_V2_PACKET_SAMPLES);
if (p) if (p)
*p = '%'; *p = '%';
@ -1248,7 +1254,6 @@ raop_make_sdp(struct raop_session *rs, struct evrtsp_request *req, char *address
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_LOG, L_RAOP, "Out of memory for SDP payload\n"); DPRINTF(E_LOG, L_RAOP, "Out of memory for SDP payload\n");
return -1; return -1;
} }
@ -1528,11 +1533,12 @@ raop_send_req_announce(struct raop_session *rs, evrtsp_req_cb cb)
char *address; char *address;
char *intf; char *intf;
unsigned short port; unsigned short port;
int family;
uint32_t session_id; uint32_t session_id;
int ret; int ret;
/* Determine local address, needed for SDP and session URL */ /* Determine local address, needed for SDP and session URL */
evrtsp_connection_get_local_address(rs->ctrl, &address, &port); evrtsp_connection_get_local_address(rs->ctrl, &address, &port, &family);
if (!address || (port == 0)) if (!address || (port == 0))
{ {
DPRINTF(E_LOG, L_RAOP, "Could not determine local address\n"); DPRINTF(E_LOG, L_RAOP, "Could not determine local address\n");
@ -1574,7 +1580,7 @@ raop_send_req_announce(struct raop_session *rs, evrtsp_req_cb cb)
} }
/* SDP payload */ /* SDP payload */
ret = raop_make_sdp(rs, req, address, session_id); ret = raop_make_sdp(rs, req, address, family, session_id);
free(address); free(address);
if (ret < 0) if (ret < 0)
{ {
@ -1992,6 +1998,7 @@ raop_session_make(struct output_device *rd, int family, output_status_cb cb)
rs->devname = strdup(rd->name); rs->devname = strdup(rd->name);
rs->address = strdup(address); rs->address = strdup(address);
rs->family = family;
rs->volume = rd->volume; rs->volume = rd->volume;