mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-21 21:28:08 +00:00
update ICE to format of latest draft-19
git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@281 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
parent
fc57866199
commit
b3edee9bd4
2 changed files with 252 additions and 218 deletions
|
|
@ -33,27 +33,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define INVALID 5
|
||||
|
||||
struct SdpCandidate {
|
||||
int seq_num;
|
||||
char candidate_id[256];
|
||||
char password[256];
|
||||
/* mandatory attributes: draft 19 */
|
||||
int foundation;
|
||||
int component_id;
|
||||
char transport[20];
|
||||
int priority;
|
||||
char conn_addr[64];
|
||||
int conn_port;
|
||||
char cand_type[20];
|
||||
char rel_addr[64];
|
||||
int rel_port;
|
||||
|
||||
char fqdn[256];
|
||||
char ipaddr[256];
|
||||
int port;
|
||||
|
||||
int mapped_port;
|
||||
int peer_derived; /* 0: local 1: stun 2: turn */
|
||||
|
||||
float priority;
|
||||
/* optionnal attributes: draft 19 */
|
||||
char extension_attr[512]; /* *(SP extension-att-name SP extension-att-value) */
|
||||
};
|
||||
|
||||
struct CandidatePair {
|
||||
|
||||
struct SdpCandidate local_candidate;
|
||||
struct SdpCandidate remote_candidate;
|
||||
int max_sn;
|
||||
int min_sn;
|
||||
char max_candidate_id[256];
|
||||
long long pair_priority;
|
||||
/* additionnal information */
|
||||
char loc_ice_ufrag[256];
|
||||
char loc_ice_pwd[256];
|
||||
char rem_ice_ufrag[256];
|
||||
char rem_ice_pwd[256];
|
||||
int rem_controlling;
|
||||
UInt64 rem_controlvalue;
|
||||
UInt96 tid;
|
||||
int connectivity_check;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,13 +28,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "mediastreamer2/ice.h"
|
||||
#include "mediastreamer2/mscommon.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static void
|
||||
ice_sendtest( Socket myFd, StunAddress4 *dest,
|
||||
ice_sendtest( struct CandidatePair *remote_candidate, Socket myFd, StunAddress4 *dest,
|
||||
const StunAtrString *username, const StunAtrString *password,
|
||||
int testNum, bool_t verbose , UInt96 *tid);
|
||||
|
||||
static void
|
||||
ice_sendtest( Socket myFd, StunAddress4 *dest,
|
||||
ice_sendtest( struct CandidatePair *remote_candidate, Socket myFd, StunAddress4 *dest,
|
||||
const StunAtrString *username, const StunAtrString *password,
|
||||
int testNum, bool_t verbose , UInt96 *tid)
|
||||
{
|
||||
|
|
@ -71,11 +73,41 @@ ice_sendtest( Socket myFd, StunAddress4 *dest,
|
|||
}
|
||||
|
||||
memset(&req, 0, sizeof(StunMessage));
|
||||
|
||||
|
||||
stunBuildReqSimple( &req, username,
|
||||
changePort , changeIP ,
|
||||
testNum );
|
||||
|
||||
req.hasMessageIntegrity=TRUE;
|
||||
|
||||
req.hasPriority = TRUE;
|
||||
req.priority.priority = pow(2,24)*(110) + pow(2,8)*(65535) + pow(2,0)*(256 - remote_candidate->remote_candidate.component_id);
|
||||
|
||||
/* TODO: put this parameter only for the candidate selected */
|
||||
if (remote_candidate->connectivity_check==VALID)
|
||||
req.hasUseCandidate = TRUE;
|
||||
|
||||
if (remote_candidate->rem_controlvalue==0)
|
||||
{
|
||||
/* calculated once only */
|
||||
remote_candidate->rem_controlvalue = random();
|
||||
remote_candidate->rem_controlvalue = remote_candidate->rem_controlvalue >> 32;
|
||||
remote_candidate->rem_controlvalue = random();
|
||||
}
|
||||
|
||||
if (remote_candidate->rem_controlling==1)
|
||||
{
|
||||
req.hasIceControlled = TRUE;
|
||||
req.iceControlled.value = remote_candidate->rem_controlvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.hasIceControlling = TRUE;
|
||||
req.iceControlling.value = remote_candidate->rem_controlvalue;
|
||||
}
|
||||
|
||||
/* TODO: not yet implemented? */
|
||||
req.hasFingerprint = TRUE;
|
||||
|
||||
len = stunEncodeMessage( &req, buf, len, password );
|
||||
|
||||
memcpy(tid , &(req.msgHdr.tr_id), sizeof(req.msgHdr.tr_id));
|
||||
|
|
@ -115,54 +147,40 @@ int ice_sound_send_stun_request(RtpSession *session, struct CandidatePair *remot
|
|||
}
|
||||
#endif
|
||||
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++)
|
||||
for (pos=0;pos<1 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++)
|
||||
{
|
||||
int media_socket = rtp_session_get_rtp_socket(session);
|
||||
StunAddress4 stunServerAddr;
|
||||
StunAtrString username;
|
||||
StunAtrString password;
|
||||
bool_t res;
|
||||
#if 0
|
||||
int pad_size;
|
||||
|
||||
#endif
|
||||
|
||||
struct CandidatePair *cand_pair = &remote_candidates[pos];
|
||||
username.sizeValue = 0;
|
||||
password.sizeValue = 0;
|
||||
|
||||
/* set username to L3:1:R2:1 */
|
||||
snprintf(username.value, sizeof(username.value), "%s:%i:%s:%i",
|
||||
cand_pair->local_candidate.candidate_id,
|
||||
1,
|
||||
cand_pair->remote_candidate.candidate_id,
|
||||
1);
|
||||
/* username comes from "ice-ufrag" (rfrag:lfrag) */
|
||||
/* ufrag and pwd are in first row only */
|
||||
snprintf(username.value, sizeof(username.value), "%s:%s",
|
||||
remote_candidates[0].rem_ice_ufrag,
|
||||
remote_candidates[0].loc_ice_ufrag);
|
||||
username.sizeValue = (UInt16)strlen(username.value);
|
||||
pad_size = username.sizeValue % 4;
|
||||
|
||||
username.value[username.sizeValue]='\0';
|
||||
username.value[username.sizeValue+1]='\0';
|
||||
username.value[username.sizeValue+2]='\0';
|
||||
username.value[username.sizeValue+3]='\0';
|
||||
|
||||
username.sizeValue = username.sizeValue + 4 - pad_size;
|
||||
|
||||
|
||||
snprintf(password.value, sizeof(password.value), "%s",
|
||||
cand_pair->remote_candidate.password);
|
||||
remote_candidates[0].rem_ice_pwd);
|
||||
password.sizeValue = (UInt16)strlen(password.value);
|
||||
|
||||
#if 0
|
||||
pad_size = password.sizeValue%4;
|
||||
password.value[password.sizeValue]='\0';
|
||||
password.value[password.sizeValue+1]='\0';
|
||||
password.value[password.sizeValue+2]='\0';
|
||||
password.value[password.sizeValue+3]='\0';
|
||||
password.sizeValue = password.sizeValue + pad_size;
|
||||
#endif
|
||||
|
||||
res = stunParseServerName(cand_pair->remote_candidate.ipaddr,
|
||||
res = stunParseServerName(cand_pair->remote_candidate.conn_addr,
|
||||
&stunServerAddr);
|
||||
if ( res == TRUE )
|
||||
{
|
||||
stunServerAddr.port = cand_pair->remote_candidate.port;
|
||||
ice_sendtest(media_socket, &stunServerAddr, &username, &password, 1, 0/*FALSE*/,
|
||||
stunServerAddr.port = cand_pair->remote_candidate.conn_port;
|
||||
ice_sendtest(&remote_candidates[pos], media_socket, &stunServerAddr, &username, &password, 1, 0/*FALSE*/,
|
||||
&(cand_pair->tid));
|
||||
}
|
||||
}
|
||||
|
|
@ -218,6 +236,16 @@ _ice_get_localip_for (struct sockaddr_storage *saddr, size_t saddr_len, char *lo
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_ice_createErrorResponse(StunMessage *response, int cl, int number, const char* msg)
|
||||
{
|
||||
response->msgHdr.msgType = (STUN_METHOD_BINDING | STUN_ERR_RESP);
|
||||
response->hasErrorCode = TRUE;
|
||||
response->errorCode.errorClass = cl;
|
||||
response->errorCode.number = number;
|
||||
strcpy(response->errorCode.reason, msg);
|
||||
}
|
||||
|
||||
int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_candidates, OrtpEvent *evt)
|
||||
{
|
||||
int switch_to_address = -1;
|
||||
|
|
@ -241,6 +269,12 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (remote_candidates==NULL)
|
||||
{
|
||||
ms_error("ice.c: dropping STUN packet: ice is not configured");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset (src6host, 0, sizeof (src6host));
|
||||
|
||||
{
|
||||
|
|
@ -266,9 +300,9 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
src6host, recvport);
|
||||
}
|
||||
|
||||
if (remote_candidates!=NULL) {
|
||||
{
|
||||
int pos;
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++)
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++)
|
||||
{
|
||||
struct CandidatePair *cand_pair = &remote_candidates[pos];
|
||||
#ifdef RESTRICTIVE_ICE
|
||||
|
|
@ -290,189 +324,183 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
}
|
||||
}
|
||||
|
||||
if (STUN_IS_REQUEST(msg.msgHdr.msgType))
|
||||
{
|
||||
if (STUN_IS_REQUEST(msg.msgHdr.msgType))
|
||||
{
|
||||
StunMessage resp;
|
||||
StunAddress4 dest;
|
||||
StunAtrString hmacPassword;
|
||||
StunAddress4 from;
|
||||
StunAddress4 myAddr;
|
||||
StunAddress4 myAltAddr;
|
||||
bool_t changePort = FALSE;
|
||||
bool_t changeIp = FALSE;
|
||||
struct sockaddr_storage name;
|
||||
socklen_t namelen;
|
||||
char localip[128];
|
||||
StunAddress4 remote_addr;
|
||||
int rtp_socket;
|
||||
memset(&name, '\0', sizeof(struct sockaddr_storage));
|
||||
memset(localip, '\0', sizeof(localip));
|
||||
_ice_get_localip_for ((struct sockaddr_storage*)&evt_data->ep->addr, evt_data->ep->addrlen, localip, 128);
|
||||
|
||||
from.addr = ntohl(udp_remote->sin_addr.s_addr);
|
||||
from.port = ntohs(udp_remote->sin_port);
|
||||
|
||||
namelen = sizeof(struct sockaddr_storage);
|
||||
memset( &resp, 0 , sizeof(resp));
|
||||
remote_addr.addr = ntohl(udp_remote->sin_addr.s_addr);
|
||||
remote_addr.port = ntohs(udp_remote->sin_port);
|
||||
|
||||
rtp_socket = rtp_session_get_rtp_socket(session);
|
||||
i = getsockname(rtp_socket, (struct sockaddr*)&name, &namelen);
|
||||
if (i!=0)
|
||||
{
|
||||
ms_error("ice.c: getsockname failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
resp.msgHdr.magic_cookie = ntohl(msg.msgHdr.magic_cookie);
|
||||
for (i=0; i<12; i++ )
|
||||
{
|
||||
resp.msgHdr.tr_id.octet[i] = msg.msgHdr.tr_id.octet[i];
|
||||
}
|
||||
|
||||
/* check mandatory params */
|
||||
|
||||
if (!msg.hasUsername)
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("Missing USERNAME attribute in connectivity check");
|
||||
_ice_createErrorResponse(&resp, 4, 32, "Missing USERNAME attribute");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
if (!msg.hasMessageIntegrity)
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("Missing MESSAGEINTEGRITY attribute in connectivity check");
|
||||
_ice_createErrorResponse(&resp, 4, 1, "Missing MESSAGEINTEGRITY attribute");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
myAddr.port = ntohs (((struct sockaddr_in*)&name)->sin_port);
|
||||
i = stunParseHostName(localip, &myAddr.addr, &myAddr.port, myAddr.port);
|
||||
if (!i)
|
||||
{
|
||||
ms_error("ice.c: stunParseHostName failed.");
|
||||
return -1;
|
||||
}
|
||||
myAddr.port = ntohs (((struct sockaddr_in*)&name)->sin_port);
|
||||
|
||||
/* changed-address set to local address/port */
|
||||
myAltAddr = myAddr;
|
||||
dest.addr = 0;
|
||||
dest.port = 0;
|
||||
|
||||
res = stunServerProcessMsg((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr,
|
||||
&from,
|
||||
&myAddr,
|
||||
&myAltAddr,
|
||||
&resp,
|
||||
&dest,
|
||||
&hmacPassword,
|
||||
&changePort,
|
||||
&changeIp );
|
||||
|
||||
if (!res)
|
||||
{
|
||||
ms_error("ice.c: Failed to process STUN request.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (changePort == TRUE || changeIp == TRUE)
|
||||
{
|
||||
ms_error("ice.c: STUN request with changePort or changeIP refused.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res=TRUE;
|
||||
if ( dest.addr == 0 ) res=FALSE;
|
||||
if ( dest.port == 0 ) res=FALSE;
|
||||
if (!res)
|
||||
{
|
||||
ms_error("ice.c: Missing destination value for response.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (msg.hasUsername!=TRUE || msg.username.sizeValue<=0)
|
||||
{
|
||||
/* reply 430 */
|
||||
ms_error("ice.c: Missing or bad username value.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
USERNAME is considered valid if its topmost portion (the part up to,
|
||||
but not including the second colon) corresponds to a transport address
|
||||
ID known to the agent.
|
||||
*/
|
||||
if (remote_candidates!=NULL) {
|
||||
int pos;
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++)
|
||||
{
|
||||
char username[256];
|
||||
struct CandidatePair *cand_pair = &remote_candidates[pos];
|
||||
size_t len = strlen(cand_pair->remote_candidate.candidate_id);
|
||||
|
||||
if (cand_pair->connectivity_check == VALID)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
memset(username, '\0', sizeof(username));
|
||||
snprintf(username, sizeof(username), "%s:%i:%s:%i",
|
||||
cand_pair->remote_candidate.candidate_id,
|
||||
1,
|
||||
cand_pair->local_candidate.candidate_id,
|
||||
1);
|
||||
|
||||
if (len+3<msg.username.sizeValue
|
||||
&& strncmp(msg.username.value, cand_pair->remote_candidate.candidate_id, len)==0)
|
||||
{
|
||||
char tmp[10];
|
||||
int k;
|
||||
snprintf(tmp, 10, "%s", msg.username.value + len +1);
|
||||
for (k=0;k<10;k++)
|
||||
{
|
||||
if (tmp[k]=='\0')
|
||||
break;
|
||||
if (tmp[k]==':')
|
||||
{
|
||||
tmp[k]='\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
k = atoi(tmp);
|
||||
/* TODO support for 2 stream RTP+RTCP */
|
||||
if (k>0 && k<10 && k==1)
|
||||
{
|
||||
/* candidate-id found! */
|
||||
#if 0
|
||||
ms_message("ice.c: Find candidate id (index=%i) for incoming STUN request.", pos);
|
||||
#endif
|
||||
|
||||
if (strncmp(msg.username.value, username, strlen(username))==0)
|
||||
{
|
||||
#ifdef RESTRICTIVE_ICE
|
||||
ms_message("ice.c: Valid STUN request received (to=%s:%i from=%s:%i).",
|
||||
cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port,
|
||||
src6host, recvport);
|
||||
/* We can't be sure the remote end will receive our answer:
|
||||
connection could be only one way...
|
||||
*/
|
||||
if (cand_pair->connectivity_check != VALID)
|
||||
{
|
||||
switch_to_address = pos;
|
||||
}
|
||||
#else
|
||||
switch_to_address = pos;
|
||||
#endif
|
||||
if (cand_pair->connectivity_check == RECV_VALID
|
||||
|| cand_pair->connectivity_check == VALID)
|
||||
{
|
||||
if (cand_pair->connectivity_check != VALID)
|
||||
{
|
||||
switch_to_address = pos;
|
||||
ms_message("ice.c: candidate id (index=%i) moved in VALID state (stunbindingrequest received).", pos);
|
||||
cand_pair->connectivity_check = VALID;
|
||||
}
|
||||
}
|
||||
else
|
||||
cand_pair->connectivity_check = SEND_VALID;
|
||||
|
||||
/* we have a VALID one */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remote_candidates==NULL)
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("no password for checking MESSAGEINTEGRITY");
|
||||
_ice_createErrorResponse(&resp, 4, 1, "no password for checking MESSAGEINTEGRITY");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
The password associated with that transport address ID is used to verify
|
||||
the MESSAGE-INTEGRITY attribute, if one was present in the request.
|
||||
*/
|
||||
char hmac[20];
|
||||
stunCalculateIntegrity_shortterm(hmac, (char*)mp->b_rptr, mp->b_wptr-mp->b_rptr-24, remote_candidates[0].loc_ice_pwd);
|
||||
if (memcmp(msg.messageIntegrity.hash, hmac, 20)!=0)
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("Wrong MESSAGEINTEGRITY attribute in connectivity check (%s)", msg.messageIntegrity.hash, hmac);
|
||||
_ice_createErrorResponse(&resp, 4, 1, "Wrong MESSAGEINTEGRITY attribute");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* 7.2.1.1. Detecting and Repairing Role Conflicts */
|
||||
/* TODO */
|
||||
if (!msg.hasIceControlling && !msg.hasIceControlled)
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("Missing either ICE-CONTROLLING or ICE-CONTROLLED attribute");
|
||||
_ice_createErrorResponse(&resp, 4, 87, "Missing either ICE-CONTROLLING or ICE-CONTROLLED attribute");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((remote_candidates[0].rem_controlling==0 && msg.hasIceControlling)
|
||||
||(remote_candidates[0].rem_controlling==1 && msg.hasIceControlled))
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
ms_error("487 Role Conflict");
|
||||
_ice_createErrorResponse(&resp, 4, 87, "Role Conflict");
|
||||
len = stunEncodeMessage(&resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 7.2.1.3. Learning Peer Reflexive Candidates */
|
||||
#if 0
|
||||
if () /* found in table */
|
||||
{
|
||||
resp.hasPriority = TRUE;
|
||||
resp.priority.priority = msg.priority.priority;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* TODO: the current algo is not ICE, but give similar results */
|
||||
int pos;
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++)
|
||||
{
|
||||
struct CandidatePair *cand_pair = &remote_candidates[pos];
|
||||
|
||||
if (cand_pair->connectivity_check == VALID)
|
||||
{
|
||||
/* already found a valid check with highest priority */
|
||||
break;
|
||||
}
|
||||
|
||||
/* connectivity check is coming from a known remote candidate?
|
||||
we should also check the port...
|
||||
*/
|
||||
if (strcmp(cand_pair->remote_candidate.conn_addr, src6host)==0)
|
||||
{
|
||||
/* working one way: use it */
|
||||
switch_to_address = pos;
|
||||
if (cand_pair->connectivity_check == RECV_VALID
|
||||
|| cand_pair->connectivity_check == VALID)
|
||||
{
|
||||
if (cand_pair->connectivity_check != VALID)
|
||||
{
|
||||
switch_to_address = pos;
|
||||
ms_message("ice.c: candidate id (index=%i) moved in VALID state (stunbindingrequest received).", pos);
|
||||
cand_pair->connectivity_check = VALID;
|
||||
}
|
||||
}
|
||||
else
|
||||
cand_pair->connectivity_check = SEND_VALID;
|
||||
|
||||
/* we have a VALID one */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UInt32 cookie = 0x2112A442;
|
||||
resp.hasXorMappedAddress = TRUE;
|
||||
resp.xorMappedAddress.ipv4.port = remote_addr.port^(cookie>>16);
|
||||
resp.xorMappedAddress.ipv4.addr = remote_addr.addr^cookie;
|
||||
|
||||
|
||||
resp.msgHdr.msgType = (STUN_METHOD_BINDING | STUN_SUCCESS_RESP);
|
||||
|
||||
resp.hasUsername = TRUE;
|
||||
memcpy(resp.username.value, msg.username.value, msg.username.sizeValue );
|
||||
resp.username.sizeValue = msg.username.sizeValue;
|
||||
|
||||
/* ? any messageintegrity in response? */
|
||||
resp.hasMessageIntegrity = TRUE;
|
||||
|
||||
const char serverName[] = "mediastreamer2 " STUN_VERSION;
|
||||
resp.hasSoftware = TRUE;
|
||||
memcpy( resp.softwareName.value, serverName, sizeof(serverName));
|
||||
resp.softwareName.sizeValue = sizeof(serverName);
|
||||
|
||||
{
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
char buf[STUN_MAX_MESSAGE_SIZE];
|
||||
int len = sizeof(buf);
|
||||
len = stunEncodeMessage( &resp, buf, len, &hmacPassword );
|
||||
if (len)
|
||||
sendMessage( rtp_socket, buf, len, dest.addr, dest.port);
|
||||
sendMessage( rtp_socket, buf, len, remote_addr.addr, remote_addr.port);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (STUN_IS_SUCCESS_RESP(msg.msgHdr.msgType))
|
||||
{
|
||||
/* set state to RECV-VALID or VALID */
|
||||
|
|
@ -491,7 +519,7 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
|
||||
if (remote_candidates!=NULL) {
|
||||
int pos;
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++)
|
||||
for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.conn_addr[0]!='\0';pos++)
|
||||
{
|
||||
struct CandidatePair *cand_pair = &remote_candidates[pos];
|
||||
|
||||
|
|
@ -504,7 +532,7 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
}
|
||||
#if 0
|
||||
ms_message("ice.c: Valid STUN answer received (to=%s:%i from=%s:%i)",
|
||||
cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port,
|
||||
cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.conn_port,
|
||||
src6host, recvport);
|
||||
#endif
|
||||
if (cand_pair->connectivity_check == SEND_VALID
|
||||
|
|
@ -513,7 +541,7 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
if (cand_pair->connectivity_check != VALID)
|
||||
{
|
||||
ms_message("ice.c: Switch to VALID mode for (to=%s:%i from=%s:%i)",
|
||||
cand_pair->remote_candidate.ipaddr, cand_pair->remote_candidate.port,
|
||||
cand_pair->remote_candidate.conn_addr, cand_pair->remote_candidate.conn_port,
|
||||
src6host, recvport);
|
||||
cand_pair->connectivity_check = VALID;
|
||||
}
|
||||
|
|
@ -539,7 +567,7 @@ int ice_process_stun_message(RtpSession *session, struct CandidatePair *remote_c
|
|||
{
|
||||
/* rtp_in_direct_mode = 1; */
|
||||
/* current destination address: snprintf(rtp_remote_addr, 256, "%s:%i", src6host, recvport); */
|
||||
ms_warning("ice.c: Modifying remote socket: symmetric RTP (%s:%i)\n",
|
||||
ms_warning("ice.c: Modifying remote destination for RTP stream (%s:%i)\n",
|
||||
src6host, recvport);
|
||||
memcpy(&session->rtp.rem_addr, &evt_data->ep->addr, evt_data->ep->addrlen);
|
||||
session->rtp.rem_addrlen=evt_data->ep->addrlen;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue