借用Licdoe的代碼來分析下ICE的實現
首先licode 用了兩套ice庫,不知道爲啥,nicer 和Libnicer ,但感覺比較偏重於libnicer,所有着重以Libnice爲主
二者分家的地方在 DtlsTransport類的構造函數中
licode 的底層傳輸採用了dtls的協議,這塊不着重分析,知道就可以了。
下面開始
第一個問題:
ICE的線程模型
ICE代碼還沒看,但從Licode的應用來看,線程是由外面給出的,這個從ICE的使用說明可以看到:
具體使用情況也是需要傳進一個Loop,
第二個問題:
ICE的底層傳輸用的那一套
現在看來,ICE的底層庫,應該是本身自帶的Udp庫
第三個問題: ICE是數據封裝層,它和應用層的關係如何
ICE的上層應用是dtls ,證據如下
listerner被設置爲了dtls的實例,
dtl也是個中間層,主要負責數據加密解密,如果輸在從上層傳過來,dtls會直接給ice,代碼如下
當有數據從ICE上來是,會首先給dtls
void DtlsTransport::onIceData(packetPtr packet) {
if (!running_) {
return;
}
int len = packet->length;
char *data = packet->data;
unsigned int component_id = packet->comp;
int length = len;
SrtpChannel *srtp = srtp_.get();
if (DtlsTransport::isDtlsPacket(data, len)) {
ELOG_DEBUG("%s message: Received DTLS message, transportName: %s, componentId: %u",
toLog(), transport_name.c_str(), component_id);
if (component_id == 1) {
std::lock_guard<std::mutex> guard(dtls_mutex);
dtlsRtp->read(reinterpret_cast<unsigned char*>(data), len);
} else {
std::lock_guard<std::mutex> guard(dtls_mutex);
dtlsRtcp->read(reinterpret_cast<unsigned char*>(data), len);
}
return;
} else if (this->getTransportState() == TRANSPORT_READY) {
std::shared_ptr<DataPacket> unprotect_packet = std::make_shared<DataPacket>(component_id,
data, len, VIDEO_PACKET, packet->received_time_ms);
if (dtlsRtcp != NULL && component_id == 2) {
srtp = srtcp_.get();
}
if (srtp != NULL) {
RtcpHeader *chead = reinterpret_cast<RtcpHeader*>(unprotect_packet->data);
if (chead->isRtcp()) {
if (srtp->unprotectRtcp(unprotect_packet->data, &unprotect_packet->length) < 0) {
return;
}
} else {
if (srtp->unprotectRtp(unprotect_packet->data, &unprotect_packet->length) < 0) {
return;
}
}
} else {
return;
}
if (length <= 0) {
return;
}
if (auto listener = getTransportListener().lock()) {
listener->onTransportData(unprotect_packet, this);
}
}
}
這段代碼首先判斷是否屬於dtls的包,如果是,那麼處理dtls,奇怪爲啥這裏分爲rtp和rtcp兩個動作
如果不是dtls的包,那麼首先解密rtp
然後把解析出來的數據,傳給listener
這個listener是什麼意思呢?
這個listerner是webrtcconnection的實例,這樣數據就流入到了webrtc裏面
可以看到數據進入到了media_stream裏面
這樣這個流程就結束了
所以,licode裏的協議棧順序爲:
UDP---ICE---DTLS----SRTP----RTP
這樣的