日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RTMPdump(libRTMP)源代码分析 4: 连接第一步——握手(Hand Shake)

發布時間:2024/2/28 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RTMPdump(libRTMP)源代码分析 4: 连接第一步——握手(Hand Shake) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

=====================================================

RTMPdump(libRTMP) 源代碼分析系列文章:

RTMPdump 源代碼分析?1: main()函數

RTMPDump (libRTMP) 源代碼分析2:解析RTMP地址——RTMP_ParseURL()

RTMPdump (libRTMP) 源代碼分析3: AMF編碼

RTMPdump (libRTMP) 源代碼分析4: 連接第一步——握手 (HandShake)

RTMPdump (libRTMP) 源代碼分析5: 建立一個流媒體連接 ?(NetConnection部分)

RTMPdump (libRTMP) 源代碼分析6: 建立一個流媒體連接 ?(NetStream部分 1)

RTMPdump (libRTMP) 源代碼分析7: 建立一個流媒體連接 ?(NetStream部分 2)

RTMPdump (libRTMP) 源代碼分析8: 發送消息 (Message)

RTMPdump (libRTMP) 源代碼分析9: 接收消息 (Message) ?(接收視音頻數據)

RTMPdump (libRTMP) 源代碼分析10: 處理各種消息 (Message)

=====================================================


函數調用結構圖

RTMPDump (libRTMP)的整體的函數調用結構圖如下圖所示。


單擊查看大圖

詳細分析

在這里分析一下RTMPdump(libRTMP)連接到支持RTMP協議的服務器的第一步:握手(Hand Shake)。

RTMP連接的過程曾經分析過:RTMP流媒體播放過程

在這里不再細說,分析一下位于handshake.h文件里面實現握手(HandShake)功能的函數:

注意:handshake.h里面代碼量很大,但是很多代碼都是為了處理RTMP的加密版協議的,例如rtmps;因此在這里就不做過多分析了,我們只考慮普通的RTMP協議。


[cpp]?view plaincopy
  • static?int??
  • HandShake(RTMP?*?r,?int?FP9HandShake)??
  • {??
  • ??int?i,?offalg?=?0;??
  • ??int?dhposClient?=?0;??
  • ??int?digestPosClient?=?0;??
  • ??int?encrypted?=?r->Link.protocol?&?RTMP_FEATURE_ENC;??
  • ??
  • ??RC4_handle?keyIn?=?0;??
  • ??RC4_handle?keyOut?=?0;??
  • ??
  • ??int32_t?*ip;??
  • ??uint32_t?uptime;??
  • ??
  • ??uint8_t?clientbuf[RTMP_SIG_SIZE?+?4],?*clientsig=clientbuf+4;??
  • ??uint8_t?serversig[RTMP_SIG_SIZE],?client2[RTMP_SIG_SIZE],?*reply;??
  • ??uint8_t?type;??
  • ??getoff?*getdh?=?NULL,?*getdig?=?NULL;??
  • ??
  • ??if?(encrypted?||?r->Link.SWFSize)??
  • ????FP9HandShake?=?TRUE;??
  • ??else??
  • ????//普通的??
  • ????FP9HandShake?=?FALSE;??
  • ??
  • ??r->Link.rc4keyIn?=?r->Link.rc4keyOut?=?0;??
  • ??
  • ??if?(encrypted)??
  • ????{??
  • ??????clientsig[-1]?=?0x06;?/*?0x08?is?RTMPE?as?well?*/??
  • ??????offalg?=?1;??
  • ????}??
  • ??else??
  • ????//0x03代表RTMP協議的版本(客戶端要求的)??
  • ????//數組竟然能有“-1”下標??
  • ????//C0中的字段(1B)??
  • ????clientsig[-1]?=?0x03;??
  • ??
  • ??uptime?=?htonl(RTMP_GetTime());??
  • ??//void?*memcpy(void?*dest,?const?void?*src,?int?n);??
  • ??//由src指向地址為起始地址的連續n個字節的數據復制到以dest指向地址為起始地址的空間內??
  • ??//把uptime的前4字節(其實一共就4字節)數據拷貝到clientsig指向的地址中??
  • ??//C1中的字段(4B)??
  • ??memcpy(clientsig,?&uptime,?4);??
  • ??
  • ??if?(FP9HandShake)??
  • ????{??
  • ??????/*?set?version?to?at?least?9.0.115.0?*/??
  • ??????if?(encrypted)??
  • ????{??
  • ??????clientsig[4]?=?128;??
  • ??????clientsig[6]?=?3;??
  • ????}??
  • ??????else??
  • ????????{??
  • ??????clientsig[4]?=?10;??
  • ??????clientsig[6]?=?45;??
  • ????}??
  • ??????clientsig[5]?=?0;??
  • ??????clientsig[7]?=?2;??
  • ??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Client?type:?%02X",?__FUNCTION__,?clientsig[-1]);??
  • ??????getdig?=?digoff[offalg];??
  • ??????getdh??=?dhoff[offalg];??
  • ????}??
  • ??else??
  • ????{??
  • ????//void?*memset(void?*s,?int?ch,?size_t?n);將s中前n個字節替換為ch并返回s;??
  • ????//將clientsig[4]開始的4個字節替換為0??
  • ????//這是C1的字段??
  • ??????memset(&clientsig[4],?0,?4);??
  • ????}??
  • ??
  • ??/*?generate?random?data?*/??
  • #ifdef?_DEBUG??
  • ??//將clientsig+8開始的1528個字節替換為0(這是一種簡單的方法)??
  • ??//這是C1中的random字段??
  • ??memset(clientsig+8,?0,?RTMP_SIG_SIZE-8);??
  • #else??
  • ??//實際中使用rand()循環生成1528字節的偽隨機數??
  • ??ip?=?(int32_t?*)(clientsig+8);??
  • ??for?(i?=?2;?i?<?RTMP_SIG_SIZE/4;?i++)??
  • ????*ip++?=?rand();??
  • #endif??
  • ??
  • ??/*?set?handshake?digest?*/??
  • ??if?(FP9HandShake)??
  • ????{??
  • ??????if?(encrypted)??
  • ????{??
  • ??????/*?generate?Diffie-Hellmann?parameters?*/??
  • ??????r->Link.dh?=?DHInit(1024);??
  • ??????if?(!r->Link.dh)??
  • ????????{??
  • ??????????RTMP_Log(RTMP_LOGERROR,?"%s:?Couldn't?initialize?Diffie-Hellmann!",??
  • ??????????__FUNCTION__);??
  • ??????????return?FALSE;??
  • ????????}??
  • ??
  • ??????dhposClient?=?getdh(clientsig,?RTMP_SIG_SIZE);??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?DH?pubkey?position:?%d",?__FUNCTION__,?dhposClient);??
  • ??
  • ??????if?(!DHGenerateKey((DH?*)r->Link.dh))??
  • ????????{??
  • ??????????RTMP_Log(RTMP_LOGERROR,?"%s:?Couldn't?generate?Diffie-Hellmann?public?key!",??
  • ??????????__FUNCTION__);??
  • ??????????return?FALSE;??
  • ????????}??
  • ??
  • ??????if?(!DHGetPublicKey((DH?*)r->Link.dh,?&clientsig[dhposClient],?128))??
  • ????????{??
  • ??????????RTMP_Log(RTMP_LOGERROR,?"%s:?Couldn't?write?public?key!",?__FUNCTION__);??
  • ??????????return?FALSE;??
  • ????????}??
  • ????}??
  • ??
  • ??????digestPosClient?=?getdig(clientsig,?RTMP_SIG_SIZE);???/*?reuse?this?value?in?verification?*/??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Client?digest?offset:?%d",?__FUNCTION__,??
  • ??????digestPosClient);??
  • ??
  • ??????CalculateDigest(digestPosClient,?clientsig,?GenuineFPKey,?30,??
  • ??????????????&clientsig[digestPosClient]);??
  • ??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Initial?client?digest:?",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?clientsig?+?digestPosClient,??
  • ?????????SHA256_DIGEST_LENGTH);??
  • ????}??
  • ??
  • #ifdef?_DEBUG??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"Clientsig:?");??
  • ??RTMP_LogHex(RTMP_LOGDEBUG,?clientsig,?RTMP_SIG_SIZE);??
  • #endif??
  • ??//發送數據報C0+C1??
  • ??//從clientsig-1開始發,長度1536+1,兩個包合并??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。發送握手數據C0+C1");??
  • ??//-----------------------------??
  • ??if?(!WriteN(r,?(char?*)clientsig-1,?RTMP_SIG_SIZE?+?1))??
  • ????return?FALSE;??
  • ??//讀取數據報,長度1,存入type??
  • ??//是服務器的S0,表示服務器使用的RTMP版本??
  • ??if?(ReadN(r,?(char?*)&type,?1)?!=?1)??/*?0x03?or?0x06?*/??
  • ????return?FALSE;??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。接收握手數據S0");??
  • ??//-----------------------------??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?Type?Answer???:?%02X",?__FUNCTION__,?type);??
  • ??//客戶端要求的版本和服務器提供的版本不同??
  • ??if?(type?!=?clientsig[-1])??
  • ????RTMP_Log(RTMP_LOGWARNING,?"%s:?Type?mismatch:?client?sent?%d,?server?answered?%d",??
  • ????__FUNCTION__,?clientsig[-1],?type);??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。成功接收握手數據S0,服務器和客戶端版本相同");??
  • ??//-----------------------------??
  • ??//客戶端和服務端隨機序列長度是否相同??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。接收握手數據S1");??
  • ??//-----------------------------??
  • ??if?(ReadN(r,?(char?*)serversig,?RTMP_SIG_SIZE)?!=?RTMP_SIG_SIZE)??
  • ????return?FALSE;??
  • ??
  • ??/*?decode?server?response?*/??
  • ??//把serversig的前四個字節賦值給uptime??
  • ??memcpy(&uptime,?serversig,?4);??
  • ??//大端轉小端??
  • ??uptime?=?ntohl(uptime);??
  • ??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?Server?Uptime?:?%d",?__FUNCTION__,?uptime);??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?FMS?Version???:?%d.%d.%d.%d",?__FUNCTION__,?serversig[4],??
  • ??????serversig[5],?serversig[6],?serversig[7]);??
  • ??
  • ??if?(FP9HandShake?&&?type?==?3?&&?!serversig[4])??
  • ????FP9HandShake?=?FALSE;??
  • ??
  • #ifdef?_DEBUG??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"Server?signature:");??
  • ??RTMP_LogHex(RTMP_LOGDEBUG,?serversig,?RTMP_SIG_SIZE);??
  • #endif??
  • ??
  • ??if?(FP9HandShake)??
  • ????{??
  • ??????uint8_t?digestResp[SHA256_DIGEST_LENGTH];??
  • ??????uint8_t?*signatureResp?=?NULL;??
  • ??
  • ??????/*?we?have?to?use?this?signature?now?to?find?the?correct?algorithms?for?getting?the?digest?and?DH?positions?*/??
  • ??????int?digestPosServer?=?getdig(serversig,?RTMP_SIG_SIZE);??
  • ??
  • ??????if?(!VerifyDigest(digestPosServer,?serversig,?GenuineFMSKey,?36))??
  • ????{??
  • ??????RTMP_Log(RTMP_LOGWARNING,?"Trying?different?position?for?server?digest!");??
  • ??????offalg?^=?1;??
  • ??????getdig?=?digoff[offalg];??
  • ??????getdh??=?dhoff[offalg];??
  • ??????digestPosServer?=?getdig(serversig,?RTMP_SIG_SIZE);??
  • ??
  • ??????if?(!VerifyDigest(digestPosServer,?serversig,?GenuineFMSKey,?36))??
  • ????????{??
  • ??????????RTMP_Log(RTMP_LOGERROR,?"Couldn't?verify?the?server?digest");?/*?continuing?anyway?will?probably?fail?*/??
  • ??????????return?FALSE;??
  • ????????}??
  • ????}??
  • ??
  • ??????/*?generate?SWFVerification?token?(SHA256?HMAC?hash?of?decompressed?SWF,?key?are?the?last?32?bytes?of?the?server?handshake)?*/??
  • ??????if?(r->Link.SWFSize)??
  • ????{??
  • ??????const?char?swfVerify[]?=?{?0x01,?0x01?};??
  • ??????char?*vend?=?r->Link.SWFVerificationResponse+sizeof(r->Link.SWFVerificationResponse);??
  • ??
  • ??????memcpy(r->Link.SWFVerificationResponse,?swfVerify,?2);??
  • ??????AMF_EncodeInt32(&r->Link.SWFVerificationResponse[2],?vend,?r->Link.SWFSize);??
  • ??????AMF_EncodeInt32(&r->Link.SWFVerificationResponse[6],?vend,?r->Link.SWFSize);??
  • ??????HMACsha256(r->Link.SWFHash,?SHA256_DIGEST_LENGTH,??
  • ?????????????&serversig[RTMP_SIG_SIZE?-?SHA256_DIGEST_LENGTH],??
  • ?????????????SHA256_DIGEST_LENGTH,??
  • ?????????????(uint8_t?*)&r->Link.SWFVerificationResponse[10]);??
  • ????}??
  • ??
  • ??????/*?do?Diffie-Hellmann?Key?exchange?for?encrypted?RTMP?*/??
  • ??????if?(encrypted)??
  • ????{??
  • ??????/*?compute?secret?key?*/??
  • ??????uint8_t?secretKey[128]?=?{?0?};??
  • ??????int?len,?dhposServer;??
  • ??
  • ??????dhposServer?=?getdh(serversig,?RTMP_SIG_SIZE);??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Server?DH?public?key?offset:?%d",?__FUNCTION__,??
  • ????????dhposServer);??
  • ??????len?=?DHComputeSharedSecretKey((DH?*)r->Link.dh,?&serversig[dhposServer],??
  • ????????????????????128,?secretKey);??
  • ??????if?(len?<?0)??
  • ????????{??
  • ??????????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Wrong?secret?key?position!",?__FUNCTION__);??
  • ??????????return?FALSE;??
  • ????????}??
  • ??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Secret?key:?",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?secretKey,?128);??
  • ??
  • ??????InitRC4Encryption(secretKey,??
  • ????????????????(uint8_t?*)?&?serversig[dhposServer],??
  • ????????????????(uint8_t?*)?&?clientsig[dhposClient],??
  • ????????????????&keyIn,?&keyOut);??
  • ????}??
  • ??
  • ??
  • ??????reply?=?client2;??
  • #ifdef?_DEBUG??
  • ??????memset(reply,?0xff,?RTMP_SIG_SIZE);??
  • #else??
  • ??????ip?=?(int32_t?*)reply;??
  • ??????for?(i?=?0;?i?<?RTMP_SIG_SIZE/4;?i++)??
  • ????????*ip++?=?rand();??
  • #endif??
  • ??????/*?calculate?response?now?*/??
  • ??????signatureResp?=?reply+RTMP_SIG_SIZE-SHA256_DIGEST_LENGTH;??
  • ??
  • ??????HMACsha256(&serversig[digestPosServer],?SHA256_DIGEST_LENGTH,??
  • ?????????GenuineFPKey,?sizeof(GenuineFPKey),?digestResp);??
  • ??????HMACsha256(reply,?RTMP_SIG_SIZE?-?SHA256_DIGEST_LENGTH,?digestResp,??
  • ?????????SHA256_DIGEST_LENGTH,?signatureResp);??
  • ??
  • ??????/*?some?info?output?*/??
  • ??????RTMP_Log(RTMP_LOGDEBUG,??
  • ??????"%s:?Calculated?digest?key?from?secure?key?and?server?digest:?",??
  • ??????__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?digestResp,?SHA256_DIGEST_LENGTH);??
  • ??
  • #ifdef?FP10??
  • ??????if?(type?==?8?)??
  • ????????{??
  • ??????uint8_t?*dptr?=?digestResp;??
  • ??????uint8_t?*sig?=?signatureResp;??
  • ??????/*?encrypt?signatureResp?*/??
  • ??????????for?(i=0;?i<SHA256_DIGEST_LENGTH;?i+=8)??
  • ????????rtmpe8_sig(sig+i,?sig+i,?dptr[i]?%?15);??
  • ????????}??
  • #if?0??
  • ??????else?if?(type?==?9))??
  • ????????{??
  • ??????uint8_t?*dptr?=?digestResp;??
  • ??????uint8_t?*sig?=?signatureResp;??
  • ??????/*?encrypt?signatureResp?*/??
  • ??????????for?(i=0;?i<SHA256_DIGEST_LENGTH;?i+=8)??
  • ????????????rtmpe9_sig(sig+i,?sig+i,?dptr[i]?%?15);??
  • ????????}??
  • #endif??
  • #endif??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Client?signature?calculated:",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?signatureResp,?SHA256_DIGEST_LENGTH);??
  • ????}??
  • ??else??
  • ????{??
  • ????//直接賦值??
  • ??????reply?=?serversig;??
  • #if?0??
  • ??????uptime?=?htonl(RTMP_GetTime());??
  • ??????memcpy(reply+4,?&uptime,?4);??
  • #endif??
  • ????}??
  • ??
  • #ifdef?_DEBUG??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?Sending?handshake?response:?",??
  • ????__FUNCTION__);??
  • ??RTMP_LogHex(RTMP_LOGDEBUG,?reply,?RTMP_SIG_SIZE);??
  • #endif??
  • ??//把reply中的1536字節數據發送出去??
  • ??//對應C2??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。發送握手數據C2");??
  • ??//-----------------------------??
  • ??if?(!WriteN(r,?(char?*)reply,?RTMP_SIG_SIZE))??
  • ????return?FALSE;??
  • ??
  • ??/*?2nd?part?of?handshake?*/??
  • ??//讀取1536字節數據到serversig??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。讀取握手數據S2");??
  • ??//-----------------------------??
  • ??if?(ReadN(r,?(char?*)serversig,?RTMP_SIG_SIZE)?!=?RTMP_SIG_SIZE)??
  • ????return?FALSE;??
  • ??
  • #ifdef?_DEBUG??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?2nd?handshake:?",?__FUNCTION__);??
  • ??RTMP_LogHex(RTMP_LOGDEBUG,?serversig,?RTMP_SIG_SIZE);??
  • #endif??
  • ??
  • ??if?(FP9HandShake)??
  • ????{??
  • ??????uint8_t?signature[SHA256_DIGEST_LENGTH];??
  • ??????uint8_t?digest[SHA256_DIGEST_LENGTH];??
  • ??
  • ??????if?(serversig[4]?==?0?&&?serversig[5]?==?0?&&?serversig[6]?==?0??
  • ??????&&?serversig[7]?==?0)??
  • ????{??
  • ??????RTMP_Log(RTMP_LOGDEBUG,??
  • ??????????"%s:?Wait,?did?the?server?just?refuse?signed?authentication?",??
  • ??????????__FUNCTION__);??
  • ????}??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Server?sent?signature:",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?&serversig[RTMP_SIG_SIZE?-?SHA256_DIGEST_LENGTH],??
  • ?????????SHA256_DIGEST_LENGTH);??
  • ??
  • ??????/*?verify?server?response?*/??
  • ??????HMACsha256(&clientsig[digestPosClient],?SHA256_DIGEST_LENGTH,??
  • ?????????GenuineFMSKey,?sizeof(GenuineFMSKey),?digest);??
  • ??????HMACsha256(serversig,?RTMP_SIG_SIZE?-?SHA256_DIGEST_LENGTH,?digest,??
  • ?????????SHA256_DIGEST_LENGTH,?signature);??
  • ??
  • ??????/*?show?some?information?*/??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Digest?key:?",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?digest,?SHA256_DIGEST_LENGTH);??
  • ??
  • #ifdef?FP10??
  • ??????if?(type?==?8?)??
  • ????????{??
  • ??????uint8_t?*dptr?=?digest;??
  • ??????uint8_t?*sig?=?signature;??
  • ??????/*?encrypt?signature?*/??
  • ??????????for?(i=0;?i<SHA256_DIGEST_LENGTH;?i+=8)??
  • ????????rtmpe8_sig(sig+i,?sig+i,?dptr[i]?%?15);??
  • ????????}??
  • #if?0??
  • ??????else?if?(type?==?9)??
  • ????????{??
  • ??????uint8_t?*dptr?=?digest;??
  • ??????uint8_t?*sig?=?signature;??
  • ??????/*?encrypt?signatureResp?*/??
  • ??????????for?(i=0;?i<SHA256_DIGEST_LENGTH;?i+=8)??
  • ????????????rtmpe9_sig(sig+i,?sig+i,?dptr[i]?%?15);??
  • ????????}??
  • #endif??
  • #endif??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Signature?calculated:",?__FUNCTION__);??
  • ??????RTMP_LogHex(RTMP_LOGDEBUG,?signature,?SHA256_DIGEST_LENGTH);??
  • ??????if?(memcmp??
  • ??????(signature,?&serversig[RTMP_SIG_SIZE?-?SHA256_DIGEST_LENGTH],??
  • ???????SHA256_DIGEST_LENGTH)?!=?0)??
  • ????{??
  • ??????RTMP_Log(RTMP_LOGWARNING,?"%s:?Server?not?genuine?Adobe!",?__FUNCTION__);??
  • ??????return?FALSE;??
  • ????}??
  • ??????else??
  • ????{??
  • ??????RTMP_Log(RTMP_LOGDEBUG,?"%s:?Genuine?Adobe?Flash?Media?Server",?__FUNCTION__);??
  • ????}??
  • ??
  • ??????if?(encrypted)??
  • ????{??
  • ??????char?buff[RTMP_SIG_SIZE];??
  • ??????/*?set?keys?for?encryption?from?now?on?*/??
  • ??????r->Link.rc4keyIn?=?keyIn;??
  • ??????r->Link.rc4keyOut?=?keyOut;??
  • ??
  • ??
  • ??????/*?update?the?keystreams?*/??
  • ??????if?(r->Link.rc4keyIn)??
  • ????????{??
  • ??????????RC4_encrypt((RC4_KEY?*)r->Link.rc4keyIn,?RTMP_SIG_SIZE,?(uint8_t?*)?buff);??
  • ????????}??
  • ??
  • ??????if?(r->Link.rc4keyOut)??
  • ????????{??
  • ??????????RC4_encrypt((RC4_KEY?*)r->Link.rc4keyOut,?RTMP_SIG_SIZE,?(uint8_t?*)?buff);??
  • ????????}??
  • ????}??
  • ????}??
  • ??else??
  • ????{??
  • ????//int?memcmp(const?void?*buf1,?const?void?*buf2,?unsigned?int?count);?當buf1=buf2時,返回值=0???
  • ????//比較serversig和clientsig是否相等??
  • ????????//握手----------------??
  • ????????r->dlg->AppendCInfo("建立連接:第1次連接。比較握手數據簽名");??
  • ????????//-----------------------------??
  • ??????if?(memcmp(serversig,?clientsig,?RTMP_SIG_SIZE)?!=?0)??
  • ????{??
  • ????????//握手----------------??
  • ????????r->dlg->AppendCInfo("建立連接:第1次連接。握手數據簽名不匹配!");??
  • ????????//-----------------------------??
  • ??????RTMP_Log(RTMP_LOGWARNING,?"%s:?client?signature?does?not?match!",??
  • ??????????__FUNCTION__);??
  • ????}??
  • ????}??
  • ??//握手----------------??
  • ??r->dlg->AppendCInfo("建立連接:第1次連接。握手成功");??
  • ??//-----------------------------??
  • ??RTMP_Log(RTMP_LOGDEBUG,?"%s:?Handshaking?finished....",?__FUNCTION__);??
  • ??return?TRUE;??
  • }??

  • rtmpdump源代碼(Linux):http://download.csdn.net/detail/leixiaohua1020/6376561

    rtmpdump源代碼(VC 2005 工程):http://download.csdn.net/detail/leixiaohua1020/6563163


    總結

    以上是生活随笔為你收集整理的RTMPdump(libRTMP)源代码分析 4: 连接第一步——握手(Hand Shake)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。