📄 ice.c
字号:
}#else if (cand_pair->connectivity_check == VALID ||cand_pair->connectivity_check == RECV_VALID ||cand_pair->connectivity_check == SEND_VALID) { already_worked_once=pos; break; }#endif } } if (msg.msgHdr.msgType == BindRequestMsg) { StunMessage resp; StunAddress4 dest; StunAtrString hmacPassword; StunAddress4 from; StunAddress4 secondary; StunAddress4 myAddr; StunAddress4 myAltAddr; bool_t changePort = FALSE; bool_t changeIp = FALSE; struct sockaddr_storage name; socklen_t namelen; char localip[128]; 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); secondary.addr = 0; secondary.port = 0; namelen = sizeof(struct sockaddr_storage); 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; } 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, &secondary, &myAddr, &myAltAddr, &resp, &dest, &hmacPassword, &changePort, &changeIp, FALSE ); 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 */ } } } } } /* The password associated with that transport address ID is used to verify the MESSAGE-INTEGRITY attribute, if one was present in the request. */ { char buf[STUN_MAX_MESSAGE_SIZE]; int len = sizeof(buf); len = stunEncodeMessage( &resp, buf, len, &hmacPassword,FALSE ); if (len) sendMessage( rtp_socket, buf, len, dest.addr, dest.port, FALSE ); } } else { /* set state to RECV-VALID or VALID */ StunMessage resp; StunAddress4 mappedAddr; memset(&resp, 0, sizeof(StunMessage)); res = stunParseMessage((char*)mp->b_rptr, mp->b_wptr-mp->b_rptr, &resp, FALSE ); if (!res) { ms_error("ice.c: Bad format for STUN answer."); return -1; } mappedAddr = resp.mappedAddress.ipv4; if (remote_candidates!=NULL) { int pos; for (pos=0;pos<10 && remote_candidates[pos].remote_candidate.ipaddr[0]!='\0';pos++) { struct CandidatePair *cand_pair = &remote_candidates[pos]; if (memcmp(&(cand_pair->tid), &(resp.msgHdr.id), sizeof(resp.msgHdr.id))==0) { /* Youhouhouhou */ if (cand_pair->connectivity_check != VALID) { switch_to_address = pos; }#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, src6host, recvport);#endif if (cand_pair->connectivity_check == SEND_VALID || cand_pair->connectivity_check == VALID) { 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, src6host, recvport); cand_pair->connectivity_check = VALID; } } else cand_pair->connectivity_check = RECV_VALID; } } } } if (remote_candidates==NULL) { ms_warning("ice.c: STUN connectivity check is disabled but we received a STUN message (%s:%i)\n", src6host, recvport); return 0; } if (switch_to_address == -1) return 0; { /* skip symmetric RTP if any previous connection is working */ if (switch_to_address<already_worked_once || already_worked_once==-1) { /* 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", src6host, recvport); memcpy(&session->rtp.rem_addr, &evt_data->ep->addr, evt_data->ep->addrlen); session->rtp.rem_addrlen=evt_data->ep->addrlen; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -