winlin

support h264/avc codec by rtmp complex handshake(SrsComplexHandshake)

@@ -105,7 +105,7 @@ MAIN_ENTRANCES=("srs_main_server") @@ -105,7 +105,7 @@ MAIN_ENTRANCES=("srs_main_server")
105 # srs(simple rtmp server) over st(state-threads) 105 # srs(simple rtmp server) over st(state-threads)
106 ModuleLibFiles=(${LibSTfile}) 106 ModuleLibFiles=(${LibSTfile})
107 MODULE_OBJS="${CORE_OBJS[@]} ${CONFIG_OBJS[@]} ${PROTOCOL_OBJS[@]} ${MAIN_OBJS[@]}" 107 MODULE_OBJS="${CORE_OBJS[@]} ${CONFIG_OBJS[@]} ${PROTOCOL_OBJS[@]} ${MAIN_OBJS[@]}"
108 -BUILD_KEY="simple_rtmp_server" APP_MAIN="srs_main_server" APP_NAME="simple_rtmp_server" LINK_OPTIONS="-ldl" SO_PATH="" . auto/apps.sh 108 +BUILD_KEY="simple_rtmp_server" APP_MAIN="srs_main_server" APP_NAME="simple_rtmp_server" LINK_OPTIONS="-ldl -lssl" SO_PATH="" . auto/apps.sh
109 109
110 echo 'configure ok! ' 110 echo 'configure ok! '
111 111
@@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,6 +32,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 32
33 /** 33 /**
34 * Annex E. The FLV File Format 34 * Annex E. The FLV File Format
  35 +* @doc update the README.cmd
35 */ 36 */
36 class SrsCodec 37 class SrsCodec
37 { 38 {
@@ -28,15 +28,200 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,15 +28,200 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 28
29 #include <srs_core_error.hpp> 29 #include <srs_core_error.hpp>
30 #include <srs_core_log.hpp> 30 #include <srs_core_log.hpp>
  31 +#include <srs_core_auto_free.hpp>
  32 +#include <srs_core_socket.hpp>
31 33
32 -SrsComplexHandshake::SrsComplexHandshake()  
33 -{ 34 +// 68bytes FMS key which is used to sign the sever packet.
  35 +u_int8_t SrsGenuineFMSKey[] = {
  36 + 0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20,
  37 + 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c,
  38 + 0x61, 0x73, 0x68, 0x20, 0x4d, 0x65, 0x64, 0x69,
  39 + 0x61, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
  40 + 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Media Server 001
  41 + 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8,
  42 + 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57,
  43 + 0x6e, 0xec, 0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab,
  44 + 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae
  45 +}; // 68
  46 +
  47 +// 62bytes FP key which is used to sign the client packet.
  48 +u_int8_t SrsGenuineFPKey[] = {
  49 + 0x47, 0x65, 0x6E, 0x75, 0x69, 0x6E, 0x65, 0x20,
  50 + 0x41, 0x64, 0x6F, 0x62, 0x65, 0x20, 0x46, 0x6C,
  51 + 0x61, 0x73, 0x68, 0x20, 0x50, 0x6C, 0x61, 0x79,
  52 + 0x65, 0x72, 0x20, 0x30, 0x30, 0x31, // Genuine Adobe Flash Player 001
  53 + 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8,
  54 + 0x2E, 0x00, 0xD0, 0xD1, 0x02, 0x9E, 0x7E, 0x57,
  55 + 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB,
  56 + 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
  57 +}; // 62
  58 +
  59 +#include <openssl/evp.h>
  60 +#include <openssl/hmac.h>
  61 +int openssl_HMACsha256(const void* data, int data_size, const void* key, int key_size, void* digest) {
  62 + HMAC_CTX ctx;
  63 +
  64 + HMAC_CTX_init(&ctx);
  65 + HMAC_Init_ex(&ctx, (unsigned char*) key, key_size, EVP_sha256(), NULL);
  66 + HMAC_Update(&ctx, (unsigned char *) data, data_size);
  67 +
  68 + unsigned int digest_size;
  69 + HMAC_Final(&ctx, (unsigned char *) digest, &digest_size);
  70 +
  71 + HMAC_CTX_cleanup(&ctx);
  72 +
  73 + if (digest_size != 32) {
  74 + return ERROR_OpenSslSha256DigestSize;
  75 + }
  76 +
  77 + return ERROR_SUCCESS;
34 } 78 }
35 79
36 -SrsComplexHandshake::~SrsComplexHandshake() 80 +#include <openssl/dh.h>
  81 +#define RFC2409_PRIME_1024 \
  82 + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \
  83 + "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
  84 + "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \
  85 + "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
  86 + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \
  87 + "FFFFFFFFFFFFFFFF"
  88 +int __openssl_generate_key(
  89 + u_int8_t*& _private_key, u_int8_t*& _public_key, int32_t& size,
  90 + DH*& pdh, int32_t& bits_count, u_int8_t*& shared_key, int32_t& shared_key_length, BIGNUM*& peer_public_key
  91 +){
  92 + int ret = ERROR_SUCCESS;
  93 +
  94 + //1. Create the DH
  95 + if ((pdh = DH_new()) == NULL) {
  96 + ret = ERROR_OpenSslCreateDH;
  97 + return ret;
  98 + }
  99 +
  100 + //2. Create his internal p and g
  101 + if ((pdh->p = BN_new()) == NULL) {
  102 + ret = ERROR_OpenSslCreateP;
  103 + return ret;
  104 + }
  105 + if ((pdh->g = BN_new()) == NULL) {
  106 + ret = ERROR_OpenSslCreateG;
  107 + return ret;
  108 + }
  109 +
  110 + //3. initialize p, g and key length
  111 + if (BN_hex2bn(&pdh->p, RFC2409_PRIME_1024) == 0) {
  112 + ret = ERROR_OpenSslParseP1024;
  113 + return ret;
  114 + }
  115 + if (BN_set_word(pdh->g, 2) != 1) {
  116 + ret = ERROR_OpenSslSetG;
  117 + return ret;
  118 + }
  119 +
  120 + //4. Set the key length
  121 + pdh->length = bits_count;
  122 +
  123 + //5. Generate private and public key
  124 + if (DH_generate_key(pdh) != 1) {
  125 + ret = ERROR_OpenSslGenerateDHKeys;
  126 + return ret;
  127 + }
  128 +
  129 + // CreateSharedKey
  130 + if (pdh == NULL) {
  131 + ret = ERROR_OpenSslGenerateDHKeys;
  132 + return ret;
  133 + }
  134 +
  135 + if (shared_key_length != 0 || shared_key != NULL) {
  136 + ret = ERROR_OpenSslShareKeyComputed;
  137 + return ret;
  138 + }
  139 +
  140 + shared_key_length = DH_size(pdh);
  141 + if (shared_key_length <= 0 || shared_key_length > 1024) {
  142 + ret = ERROR_OpenSslGetSharedKeySize;
  143 + return ret;
  144 + }
  145 + shared_key = new u_int8_t[shared_key_length];
  146 + memset(shared_key, 0, shared_key_length);
  147 +
  148 + peer_public_key = BN_bin2bn(_private_key, size, 0);
  149 + if (peer_public_key == NULL) {
  150 + ret = ERROR_OpenSslGetPeerPublicKey;
  151 + return ret;
  152 + }
  153 +
  154 + if (DH_compute_key(shared_key, peer_public_key, pdh) == -1) {
  155 + ret = ERROR_OpenSslComputeSharedKey;
  156 + return ret;
  157 + }
  158 +
  159 + // CopyPublicKey
  160 + if (pdh == NULL) {
  161 + ret = ERROR_OpenSslComputeSharedKey;
  162 + return ret;
  163 + }
  164 +
  165 + int32_t keySize = BN_num_bytes(pdh->pub_key);
  166 + if ((keySize <= 0) || (size <= 0) || (keySize > size)) {
  167 + //("CopyPublicKey failed due to either invalid DH state or invalid call"); return ret;
  168 + ret = ERROR_OpenSslInvalidDHState;
  169 + return ret;
  170 + }
  171 +
  172 + if (BN_bn2bin(pdh->pub_key, _public_key) != keySize) {
  173 + //("Unable to copy key"); return ret;
  174 + ret = ERROR_OpenSslCopyKey;
  175 + return ret;
  176 + }
  177 +
  178 + return ret;
  179 +}
  180 +int openssl_generate_key(char* _private_key, char* _public_key, int32_t size)
37 { 181 {
  182 + int ret = ERROR_SUCCESS;
  183 +
  184 + // Initialize
  185 + DH* pdh = NULL;
  186 + int32_t bits_count = 1024;
  187 + u_int8_t* shared_key = NULL;
  188 + int32_t shared_key_length = 0;
  189 + BIGNUM* peer_public_key = NULL;
  190 +
  191 + ret = __openssl_generate_key(
  192 + (u_int8_t*&)_private_key, (u_int8_t*&)_public_key, size,
  193 + pdh, bits_count, shared_key, shared_key_length, peer_public_key
  194 + );
  195 +
  196 + if (pdh != NULL) {
  197 + if (pdh->p != NULL) {
  198 + BN_free(pdh->p);
  199 + pdh->p = NULL;
  200 + }
  201 + if (pdh->g != NULL) {
  202 + BN_free(pdh->g);
  203 + pdh->g = NULL;
  204 + }
  205 + DH_free(pdh);
  206 + pdh = NULL;
  207 + }
  208 +
  209 + if (shared_key != NULL) {
  210 + delete[] shared_key;
  211 + shared_key = NULL;
  212 + }
  213 +
  214 + if (peer_public_key != NULL) {
  215 + BN_free(peer_public_key);
  216 + peer_public_key = NULL;
  217 + }
  218 +
  219 + return ret;
38 } 220 }
39 221
  222 +// the digest key generate size.
  223 +#define OpensslHashSize 512
  224 +
40 /** 225 /**
41 * 764bytes key结构 226 * 764bytes key结构
42 * random-data: (offset)bytes 227 * random-data: (offset)bytes
@@ -60,11 +245,99 @@ struct key_block @@ -60,11 +245,99 @@ struct key_block
60 // 4bytes 245 // 4bytes
61 int32_t offset; 246 int32_t offset;
62 }; 247 };
  248 +// calc the offset of key,
  249 +// the key->offset cannot be used as the offset of key.
  250 +int srs_key_block_get_offset(key_block* key)
  251 +{
  252 + int max_offset_size = 764 - 128 - 4;
  253 +
  254 + int offset = 0;
  255 + u_int8_t* pp = (u_int8_t*)&key->offset;
  256 + offset += *pp++;
  257 + offset += *pp++;
  258 + offset += *pp++;
  259 + offset += *pp++;
  260 +
  261 + return offset % max_offset_size;
  262 +}
  263 +// create new key block data.
  264 +// if created, user must free it by srs_key_block_free
63 void srs_key_block_init(key_block* key) 265 void srs_key_block_init(key_block* key)
64 { 266 {
  267 + key->offset = (int32_t)rand();
  268 + key->random0 = NULL;
  269 + key->random1 = NULL;
  270 +
  271 + int offset = srs_key_block_get_offset(key);
  272 + srs_assert(offset >= 0);
  273 +
  274 + key->random0_size = offset;
  275 + if (key->random0_size > 0) {
  276 + key->random0 = new char[key->random0_size];
  277 + for (int i = 0; i < key->random0_size; i++) {
  278 + *(key->random0 + i) = rand() % 256;
  279 + }
  280 + }
  281 +
  282 + for (int i = 0; i < (int)sizeof(key->key); i++) {
  283 + *(key->key + i) = rand() % 256;
  284 + }
  285 +
  286 + key->random1_size = 764 - offset - 128 - 4;
  287 + if (key->random1_size > 0) {
  288 + key->random1 = new char[key->random1_size];
  289 + for (int i = 0; i < key->random1_size; i++) {
  290 + *(key->random1 + i) = rand() % 256;
  291 + }
  292 + }
65 } 293 }
  294 +// parse key block from c1s1.
  295 +// if created, user must free it by srs_key_block_free
  296 +// @c1s1_key_bytes the key start bytes, maybe c1s1 or c1s1+764
  297 +int srs_key_block_parse(key_block* key, char* c1s1_key_bytes)
  298 +{
  299 + int ret = ERROR_SUCCESS;
  300 +
  301 + char* pp = c1s1_key_bytes + 764;
  302 +
  303 + pp -= sizeof(int32_t);
  304 + key->offset = *(int32_t*)pp;
  305 +
  306 + key->random0 = NULL;
  307 + key->random1 = NULL;
  308 +
  309 + int offset = srs_key_block_get_offset(key);
  310 + srs_assert(offset >= 0);
  311 +
  312 + pp = c1s1_key_bytes;
  313 + key->random0_size = offset;
  314 + if (key->random0_size > 0) {
  315 + key->random0 = new char[key->random0_size];
  316 + memcpy(key->random0, pp, key->random0_size);
  317 + }
  318 + pp += key->random0_size;
  319 +
  320 + memcpy(key->key, pp, sizeof(key->key));
  321 + pp += sizeof(key->key);
  322 +
  323 + key->random1_size = 764 - offset - 128 - 4;
  324 + if (key->random1_size > 0) {
  325 + key->random1 = new char[key->random1_size];
  326 + memcpy(key->random1, pp, key->random1_size);
  327 + }
  328 +
  329 + return ret;
  330 +}
  331 +// free the block data create by
  332 +// srs_key_block_init or srs_key_block_parse
66 void srs_key_block_free(key_block* key) 333 void srs_key_block_free(key_block* key)
67 { 334 {
  335 + if (key->random0) {
  336 + srs_freepa(key->random0);
  337 + }
  338 + if (key->random1) {
  339 + srs_freepa(key->random1);
  340 + }
68 } 341 }
69 342
70 /** 343 /**
@@ -90,11 +363,243 @@ struct digest_block @@ -90,11 +363,243 @@ struct digest_block
90 char* random1; 363 char* random1;
91 int random1_size; 364 int random1_size;
92 }; 365 };
  366 +// calc the offset of digest,
  367 +// the key->offset cannot be used as the offset of digest.
  368 +int srs_digest_block_get_offset(digest_block* digest)
  369 +{
  370 + int max_offset_size = 764 - 32 - 4;
  371 +
  372 + int offset = 0;
  373 + u_int8_t* pp = (u_int8_t*)&digest->offset;
  374 + offset += *pp++;
  375 + offset += *pp++;
  376 + offset += *pp++;
  377 + offset += *pp++;
  378 +
  379 + return offset % max_offset_size;
  380 +}
  381 +// create new digest block data.
  382 +// if created, user must free it by srs_digest_block_free
93 void srs_digest_block_init(digest_block* digest) 383 void srs_digest_block_init(digest_block* digest)
94 { 384 {
  385 + digest->offset = (int32_t)rand();
  386 + digest->random0 = NULL;
  387 + digest->random1 = NULL;
  388 +
  389 + int offset = srs_digest_block_get_offset(digest);
  390 + srs_assert(offset >= 0);
  391 +
  392 + digest->random0_size = offset;
  393 + if (digest->random0_size > 0) {
  394 + digest->random0 = new char[digest->random0_size];
  395 + for (int i = 0; i < digest->random0_size; i++) {
  396 + *(digest->random0 + i) = rand() % 256;
  397 + }
  398 + }
  399 +
  400 + for (int i = 0; i < (int)sizeof(digest->digest); i++) {
  401 + *(digest->digest + i) = rand() % 256;
  402 + }
  403 +
  404 + digest->random1_size = 764 - 4 - offset - 32;
  405 + if (digest->random1_size > 0) {
  406 + digest->random1 = new char[digest->random1_size];
  407 + for (int i = 0; i < digest->random1_size; i++) {
  408 + *(digest->random1 + i) = rand() % 256;
  409 + }
  410 + }
  411 +}
  412 +// parse digest block from c1s1.
  413 +// if created, user must free it by srs_digest_block_free
  414 +// @c1s1_digest_bytes the digest start bytes, maybe c1s1 or c1s1+764
  415 +int srs_digest_block_parse(digest_block* digest, char* c1s1_digest_bytes)
  416 +{
  417 + int ret = ERROR_SUCCESS;
  418 +
  419 + char* pp = c1s1_digest_bytes;
  420 +
  421 + digest->offset = *(int32_t*)pp;
  422 + pp += sizeof(int32_t);
  423 +
  424 + digest->random0 = NULL;
  425 + digest->random1 = NULL;
  426 +
  427 + int offset = srs_digest_block_get_offset(digest);
  428 + srs_assert(offset >= 0);
  429 +
  430 + digest->random0_size = offset;
  431 + if (digest->random0_size > 0) {
  432 + digest->random0 = new char[digest->random0_size];
  433 + memcpy(digest->random0, pp, digest->random0_size);
  434 + }
  435 + pp += digest->random0_size;
  436 +
  437 + memcpy(digest->digest, pp, sizeof(digest->digest));
  438 + pp += sizeof(digest->digest);
  439 +
  440 + digest->random1_size = 764 - 4 - offset - 32;
  441 + if (digest->random1_size > 0) {
  442 + digest->random1 = new char[digest->random1_size];
  443 + memcpy(digest->random1, pp, digest->random1_size);
  444 + }
  445 +
  446 + return ret;
95 } 447 }
  448 +// free the block data create by
  449 +// srs_digest_block_init or srs_digest_block_parse
96 void srs_digest_block_free(digest_block* digest) 450 void srs_digest_block_free(digest_block* digest)
97 { 451 {
  452 + if (digest->random0) {
  453 + srs_freepa(digest->random0);
  454 + }
  455 + if (digest->random1) {
  456 + srs_freepa(digest->random1);
  457 + }
  458 +}
  459 +
  460 +/**
  461 +* the schema type.
  462 +*/
  463 +enum srs_schema_type {
  464 + srs_schema0 = 0, // key-digest sequence
  465 + srs_schema1 = 1, // digest-key sequence
  466 + srs_schema_invalid = 2,
  467 +};
  468 +
  469 +void __time_copy_to(char*& pp, int32_t time)
  470 +{
  471 + // 4bytes time
  472 + *(int32_t*)pp = time;
  473 + pp += 4;
  474 +}
  475 +void __version_copy_to(char*& pp, int32_t version)
  476 +{
  477 + // 4bytes version
  478 + *(int32_t*)pp = version;
  479 + pp += 4;
  480 +}
  481 +void __key_copy_to(char*& pp, key_block* key)
  482 +{
  483 + // 764bytes key block
  484 + if (key->random0_size > 0) {
  485 + memcpy(pp, key->random0, key->random0_size);
  486 + }
  487 + pp += key->random0_size;
  488 +
  489 + memcpy(pp, key->key, sizeof(key->key));
  490 + pp += sizeof(key->key);
  491 +
  492 + if (key->random1_size > 0) {
  493 + memcpy(pp, key->random1, key->random1_size);
  494 + }
  495 + pp += key->random1_size;
  496 +
  497 + *(int32_t*)pp = key->offset;
  498 + pp += 4;
  499 +}
  500 +void __digest_copy_to(char*& pp, digest_block* digest, bool with_digest)
  501 +{
  502 + // 732bytes digest block without the 32bytes digest-data
  503 + // nbytes digest block part1
  504 + *(int32_t*)pp = digest->offset;
  505 + pp += 4;
  506 +
  507 + if (digest->random0_size > 0) {
  508 + memcpy(pp, digest->random0, digest->random0_size);
  509 + }
  510 + pp += digest->random0_size;
  511 +
  512 + // digest
  513 + if (with_digest) {
  514 + memcpy(pp, digest->digest, 32);
  515 + pp += 32;
  516 + }
  517 +
  518 + // nbytes digest block part2
  519 + if (digest->random1_size > 0) {
  520 + memcpy(pp, digest->random1, digest->random1_size);
  521 + }
  522 + pp += digest->random1_size;
  523 +}
  524 +
  525 +/**
  526 +* copy whole c1s1 to bytes.
  527 +*/
  528 +void schema0_copy_to(char* bytes, bool with_digest,
  529 + int32_t time, int32_t version, key_block* key, digest_block* digest)
  530 +{
  531 + char* pp = bytes;
  532 +
  533 + __time_copy_to(pp, time);
  534 + __version_copy_to(pp, version);
  535 + __key_copy_to(pp, key);
  536 + __digest_copy_to(pp, digest, with_digest);
  537 +
  538 + if (with_digest) {
  539 + srs_assert(pp - bytes == 1536);
  540 + } else {
  541 + srs_assert(pp - bytes == 1536 - 32);
  542 + }
  543 +}
  544 +void schema1_copy_to(char* bytes, bool with_digest,
  545 + int32_t time, int32_t version, digest_block* digest, key_block* key)
  546 +{
  547 + char* pp = bytes;
  548 +
  549 + __time_copy_to(pp, time);
  550 + __version_copy_to(pp, version);
  551 + __digest_copy_to(pp, digest, with_digest);
  552 + __key_copy_to(pp, key);
  553 +
  554 + if (with_digest) {
  555 + srs_assert(pp - bytes == 1536);
  556 + } else {
  557 + srs_assert(pp - bytes == 1536 - 32);
  558 + }
  559 +}
  560 +/**
  561 +* c1s1 is splited by digest:
  562 +* c1s1-part1: n bytes (time, version, key and digest-part1).
  563 +* digest-data: 32bytes
  564 +* c1s1-part2: (1536-n-32)bytes (digest-part2)
  565 +*/
  566 +char* bytes_join_schema0(int32_t time, int32_t version, key_block* key, digest_block* digest)
  567 +{
  568 + char* bytes = new char[1536 -32];
  569 +
  570 + schema0_copy_to(bytes, false, time, version, key, digest);
  571 +
  572 + return bytes;
  573 +}
  574 +/**
  575 +* c1s1 is splited by digest:
  576 +* c1s1-part1: n bytes (time, version and digest-part1).
  577 +* digest-data: 32bytes
  578 +* c1s1-part2: (1536-n-32)bytes (digest-part2 and key)
  579 +*/
  580 +char* bytes_join_schema1(int32_t time, int32_t version, digest_block* digest, key_block* key)
  581 +{
  582 + char* bytes = new char[1536 -32];
  583 +
  584 + schema1_copy_to(bytes, false, time, version, digest, key);
  585 +
  586 + return bytes;
  587 +}
  588 +
  589 +/**
  590 +* compare the memory in bytes.
  591 +*/
  592 +bool srs_bytes_equals(void* pa, void* pb, int size){
  593 + u_int8_t* a = (u_int8_t*)pa;
  594 + u_int8_t* b = (u_int8_t*)pb;
  595 +
  596 + for(int i = 0; i < size; i++){
  597 + if(a[i] != b[i]){
  598 + return false;
  599 + }
  600 + }
  601 +
  602 + return true;
98 } 603 }
99 604
100 /** 605 /**
@@ -111,10 +616,6 @@ void srs_digest_block_free(digest_block* digest) @@ -111,10 +616,6 @@ void srs_digest_block_free(digest_block* digest)
111 */ 616 */
112 struct c1s1 617 struct c1s1
113 { 618 {
114 - enum schema_type {  
115 - schema0 = 0,  
116 - schema1 = 1  
117 - };  
118 union block { 619 union block {
119 key_block key; 620 key_block key;
120 digest_block digest; 621 digest_block digest;
@@ -134,33 +635,443 @@ struct c1s1 @@ -134,33 +635,443 @@ struct c1s1
134 block block1; 635 block block1;
135 636
136 // the logic schema 637 // the logic schema
137 - schema_type schema; 638 + srs_schema_type schema;
138 639
139 - c1s1()  
140 - {  
141 - time = ::time(NULL);  
142 - version = 0x00;  
143 -  
144 - schema = c1s1::schema0; 640 + c1s1();
  641 + virtual ~c1s1();
  642 + /**
  643 + * get the digest key.
  644 + */
  645 + virtual char* get_digest();
  646 + /**
  647 + * copy to bytes.
  648 + */
  649 + virtual void dump(char* _c1s1);
  650 +
  651 + /**
  652 + * client: create and sign c1 by schema.
  653 + * sign the c1, generate the digest.
  654 + * calc_c1_digest(c1, schema) {
  655 + * get c1s1-joined from c1 by specified schema
  656 + * digest-data = HMACsha256(c1s1-joined, FPKey, 30)
  657 + * return digest-data;
  658 + * }
  659 + * random fill 1536bytes c1 // also fill the c1-128bytes-key
  660 + * time = time() // c1[0-3]
  661 + * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
  662 + * schema = choose schema0 or schema1
  663 + * digest-data = calc_c1_digest(c1, schema)
  664 + * copy digest-data to c1
  665 + */
  666 + virtual int c1_create(srs_schema_type _schema);
  667 + /**
  668 + * server: parse the c1s1, discovery the key and digest by schema.
  669 + * use the c1_validate_digest() to valid the digest of c1.
  670 + */
  671 + virtual int c1_parse(char* _c1s1, srs_schema_type _schema);
  672 + /**
  673 + * server: validate the parsed schema and c1s1
  674 + */
  675 + virtual int c1_validate_digest(bool& is_valid);
  676 + /**
  677 + * server: create and sign the s1 from c1.
  678 + */
  679 + virtual int s1_create(c1s1* c1);
  680 +private:
  681 + virtual int calc_s1_digest(char*& digest);
  682 + virtual int calc_c1_digest(char*& digest);
  683 + virtual void destroy_blocks();
  684 +};
  685 +
  686 +/**
  687 +* the c2s2 complex handshake structure.
  688 +* random-data: 1504bytes
  689 +* digest-data: 32bytes
  690 +*/
  691 +struct c2s2
  692 +{
  693 + char random[1504];
  694 + char digest[32];
  695 +
  696 + c2s2();
  697 + virtual ~c2s2();
  698 +
  699 + /**
  700 + * copy to bytes.
  701 + */
  702 + virtual void dump(char* _c2s2);
  703 +
  704 + /**
  705 + * create c2.
  706 + * random fill c2s2 1536 bytes
  707 + *
  708 + * // client generate C2, or server valid C2
  709 + * temp-key = HMACsha256(s1-digest, FPKey, 62)
  710 + * c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
  711 + */
  712 + virtual int c2_create(c1s1* s1);
  713 +
  714 + /**
  715 + * create s2.
  716 + * random fill c2s2 1536 bytes
  717 + *
  718 + * // server generate S2, or client valid S2
  719 + * temp-key = HMACsha256(c1-digest, FMSKey, 68)
  720 + * s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
  721 + */
  722 + virtual int s2_create(c1s1* c1);
  723 +};
  724 +
  725 +c2s2::c2s2()
  726 +{
  727 + for (int i = 0; i < 1504; i++) {
  728 + *(random + i) = rand();
  729 + }
  730 + for (int i = 0; i < 32; i++) {
  731 + *(digest + i) = rand();
  732 + }
  733 +}
  734 +
  735 +c2s2::~c2s2()
  736 +{
  737 +}
  738 +
  739 +void c2s2::dump(char* _c2s2)
  740 +{
  741 + memcpy(_c2s2, random, 1504);
  742 + memcpy(_c2s2 + 1504, digest, 32);
  743 +}
  744 +
  745 +int c2s2::c2_create(c1s1* s1)
  746 +{
  747 + int ret = ERROR_SUCCESS;
  748 +
  749 + char temp_key[OpensslHashSize];
  750 + if ((ret = openssl_HMACsha256(s1->get_digest(), 32, SrsGenuineFPKey, 62, temp_key)) != ERROR_SUCCESS) {
  751 + srs_error("create c2 temp key failed. ret=%d", ret);
  752 + return ret;
  753 + }
  754 + srs_verbose("generate c2 temp key success.");
  755 +
  756 + char _digest[OpensslHashSize];
  757 + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) {
  758 + srs_error("create c2 digest failed. ret=%d", ret);
  759 + return ret;
  760 + }
  761 + srs_verbose("generate c2 digest success.");
  762 +
  763 + memcpy(digest, _digest, 32);
  764 +
  765 + return ret;
  766 +}
  767 +
  768 +int c2s2::s2_create(c1s1* c1)
  769 +{
  770 + int ret = ERROR_SUCCESS;
  771 +
  772 + char temp_key[OpensslHashSize];
  773 + if ((ret = openssl_HMACsha256(c1->get_digest(), 32, SrsGenuineFMSKey, 68, temp_key)) != ERROR_SUCCESS) {
  774 + srs_error("create s2 temp key failed. ret=%d", ret);
  775 + return ret;
  776 + }
  777 + srs_verbose("generate s2 temp key success.");
  778 +
  779 + char _digest[OpensslHashSize];
  780 + if ((ret = openssl_HMACsha256(random, 1504, temp_key, 32, _digest)) != ERROR_SUCCESS) {
  781 + srs_error("create s2 digest failed. ret=%d", ret);
  782 + return ret;
  783 + }
  784 + srs_verbose("generate s2 digest success.");
  785 +
  786 + memcpy(digest, _digest, 32);
  787 +
  788 + return ret;
  789 +}
  790 +
  791 +c1s1::c1s1()
  792 +{
  793 + schema = srs_schema_invalid;
  794 +}
  795 +c1s1::~c1s1()
  796 +{
  797 + destroy_blocks();
  798 +}
  799 +
  800 +char* c1s1::get_digest()
  801 +{
  802 + srs_assert(schema != srs_schema_invalid);
  803 +
  804 + if (schema == srs_schema0) {
  805 + return block1.digest.digest;
  806 + } else {
  807 + return block0.digest.digest;
  808 + }
  809 +}
  810 +
  811 +void c1s1::dump(char* _c1s1)
  812 +{
  813 + srs_assert(schema != srs_schema_invalid);
  814 +
  815 + if (schema == srs_schema0) {
  816 + schema0_copy_to(_c1s1, true, time, version, &block0.key, &block1.digest);
  817 + } else {
  818 + schema1_copy_to(_c1s1, true, time, version, &block0.digest, &block1.key);
  819 + }
  820 +}
  821 +
  822 +int c1s1::c1_create(srs_schema_type _schema)
  823 +{
  824 + int ret = ERROR_SUCCESS;
  825 +
  826 + if (_schema == srs_schema_invalid) {
  827 + ret = ERROR_RTMP_CH_SCHEMA;
  828 + srs_error("create c1 failed. invalid schema=%d, ret=%d", _schema, ret);
  829 + return ret;
  830 + }
  831 +
  832 + destroy_blocks();
  833 +
  834 + time = ::time(NULL);
  835 + version = 0x02070080; // client c1 version
  836 +
  837 + if (_schema == srs_schema0) {
145 srs_key_block_init(&block0.key); 838 srs_key_block_init(&block0.key);
146 srs_digest_block_init(&block1.digest); 839 srs_digest_block_init(&block1.digest);
  840 + } else {
  841 + srs_digest_block_init(&block0.digest);
  842 + srs_key_block_init(&block1.key);
  843 + }
  844 +
  845 + schema = _schema;
  846 +
  847 + char* digest = NULL;
  848 +
  849 + if ((ret = calc_c1_digest(digest)) != ERROR_SUCCESS) {
  850 + srs_error("sign c1 error, failed to calc digest. ret=%d", ret);
  851 + return ret;
  852 + }
  853 +
  854 + srs_assert(digest != NULL);
  855 + SrsAutoFree(char, digest, true);
  856 +
  857 + if (schema == srs_schema0) {
  858 + memcpy(block1.digest.digest, digest, 32);
  859 + } else {
  860 + memcpy(block0.digest.digest, digest, 32);
  861 + }
  862 +
  863 + return ret;
  864 +}
  865 +
  866 +int c1s1::c1_parse(char* _c1s1, srs_schema_type _schema)
  867 +{
  868 + int ret = ERROR_SUCCESS;
  869 +
  870 + if (_schema == srs_schema_invalid) {
  871 + ret = ERROR_RTMP_CH_SCHEMA;
  872 + srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret);
  873 + return ret;
147 } 874 }
148 - virtual ~c1s1()  
149 - {  
150 - if (schema == c1s1::schema0) {  
151 - srs_key_block_free(&block0.key);  
152 - srs_digest_block_free(&block1.digest);  
153 - } else {  
154 - srs_digest_block_free(&block0.digest);  
155 - srs_key_block_free(&block1.key); 875 +
  876 + destroy_blocks();
  877 +
  878 + time = *(int32_t*)_c1s1;
  879 + version = *(int32_t*)(_c1s1 + 4); // client c1 version
  880 +
  881 + if (_schema == srs_schema0) {
  882 + if ((ret = srs_key_block_parse(&block0.key, _c1s1 + 8)) != ERROR_SUCCESS) {
  883 + srs_error("parse the c1 key failed. ret=%d", ret);
  884 + return ret;
  885 + }
  886 + if ((ret = srs_digest_block_parse(&block1.digest, _c1s1 + 8 + 764)) != ERROR_SUCCESS) {
  887 + srs_error("parse the c1 digest failed. ret=%d", ret);
  888 + return ret;
  889 + }
  890 + srs_verbose("parse c1 key-digest success");
  891 + } else if (_schema == srs_schema1) {
  892 + if ((ret = srs_digest_block_parse(&block0.digest, _c1s1 + 8)) != ERROR_SUCCESS) {
  893 + srs_error("parse the c1 key failed. ret=%d", ret);
  894 + return ret;
156 } 895 }
  896 + if ((ret = srs_key_block_parse(&block1.key, _c1s1 + 8 + 764)) != ERROR_SUCCESS) {
  897 + srs_error("parse the c1 digest failed. ret=%d", ret);
  898 + return ret;
  899 + }
  900 + srs_verbose("parse c1 digest-key success");
  901 + } else {
  902 + ret = ERROR_RTMP_CH_SCHEMA;
  903 + srs_error("parse c1 failed. invalid schema=%d, ret=%d", _schema, ret);
  904 + return ret;
157 } 905 }
158 -}; 906 +
  907 + schema = _schema;
  908 +
  909 + return ret;
  910 +}
  911 +
  912 +int c1s1::c1_validate_digest(bool& is_valid)
  913 +{
  914 + int ret = ERROR_SUCCESS;
  915 +
  916 + char* c1_digest = NULL;
  917 +
  918 + if ((ret = calc_c1_digest(c1_digest)) != ERROR_SUCCESS) {
  919 + srs_error("validate c1 error, failed to calc digest. ret=%d", ret);
  920 + return ret;
  921 + }
  922 +
  923 + srs_assert(c1_digest != NULL);
  924 + SrsAutoFree(char, c1_digest, true);
  925 +
  926 + if (schema == srs_schema0) {
  927 + is_valid = srs_bytes_equals(block1.digest.digest, c1_digest, 32);
  928 + } else {
  929 + is_valid = srs_bytes_equals(block0.digest.digest, c1_digest, 32);
  930 + }
  931 +
  932 + return ret;
  933 +}
  934 +
  935 +int c1s1::s1_create(c1s1* c1)
  936 +{
  937 + int ret = ERROR_SUCCESS;
  938 +
  939 + if (c1->schema == srs_schema_invalid) {
  940 + ret = ERROR_RTMP_CH_SCHEMA;
  941 + srs_error("create s1 failed. invalid schema=%d, ret=%d", c1->schema, ret);
  942 + return ret;
  943 + }
  944 +
  945 + destroy_blocks();
  946 + schema = c1->schema;
  947 +
  948 + time = ::time(NULL);
  949 + version = 0x01000504; // server s1 version
  950 +
  951 + if (schema == srs_schema0) {
  952 + srs_key_block_init(&block0.key);
  953 + srs_digest_block_init(&block1.digest);
  954 + } else {
  955 + srs_digest_block_init(&block0.digest);
  956 + srs_key_block_init(&block1.key);
  957 + }
  958 +
  959 + if (schema == srs_schema0) {
  960 + if ((ret = openssl_generate_key(c1->block0.key.key, block0.key.key, 128)) != ERROR_SUCCESS) {
  961 + srs_error("calc s1 key failed. ret=%d", ret);
  962 + return ret;
  963 + }
  964 + } else {
  965 + if ((ret = openssl_generate_key(c1->block1.key.key, block1.key.key, 128)) != ERROR_SUCCESS) {
  966 + srs_error("calc s1 key failed. ret=%d", ret);
  967 + return ret;
  968 + }
  969 + }
  970 + srs_verbose("calc s1 key success.");
  971 +
  972 + char* s1_digest = NULL;
  973 + if ((ret = calc_s1_digest(s1_digest)) != ERROR_SUCCESS) {
  974 + srs_error("calc s1 digest failed. ret=%d", ret);
  975 + return ret;
  976 + }
  977 + srs_verbose("calc s1 digest success.");
  978 +
  979 + srs_assert(s1_digest != NULL);
  980 + SrsAutoFree(char, s1_digest, true);
  981 +
  982 + if (schema == srs_schema0) {
  983 + memcpy(block1.digest.digest, s1_digest, 32);
  984 + } else {
  985 + memcpy(block0.digest.digest, s1_digest, 32);
  986 + }
  987 + srs_verbose("copy s1 key success.");
  988 +
  989 + return ret;
  990 +}
  991 +
  992 +int c1s1::calc_s1_digest(char*& digest)
  993 +{
  994 + int ret = ERROR_SUCCESS;
  995 +
  996 + srs_assert(schema == srs_schema0 || schema == srs_schema1);
  997 +
  998 + char* c1s1_joined_bytes = NULL;
  999 +
  1000 + if (schema == srs_schema0) {
  1001 + c1s1_joined_bytes = bytes_join_schema0(time, version, &block0.key, &block1.digest);
  1002 + } else {
  1003 + c1s1_joined_bytes = bytes_join_schema1(time, version, &block0.digest, &block1.key);
  1004 + }
  1005 +
  1006 + srs_assert(c1s1_joined_bytes != NULL);
  1007 + SrsAutoFree(char, c1s1_joined_bytes, true);
  1008 +
  1009 + digest = new char[OpensslHashSize];
  1010 + if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFMSKey, 36, digest)) != ERROR_SUCCESS) {
  1011 + srs_error("calc digest for s1 failed. ret=%d", ret);
  1012 + return ret;
  1013 + }
  1014 + srs_verbose("digest calculated for s1");
  1015 +
  1016 + return ret;
  1017 +}
  1018 +
  1019 +int c1s1::calc_c1_digest(char*& digest)
  1020 +{
  1021 + int ret = ERROR_SUCCESS;
  1022 +
  1023 + srs_assert(schema == srs_schema0 || schema == srs_schema1);
  1024 +
  1025 + char* c1s1_joined_bytes = NULL;
  1026 +
  1027 + if (schema == srs_schema0) {
  1028 + c1s1_joined_bytes = bytes_join_schema0(time, version, &block0.key, &block1.digest);
  1029 + } else {
  1030 + c1s1_joined_bytes = bytes_join_schema1(time, version, &block0.digest, &block1.key);
  1031 + }
  1032 +
  1033 + srs_assert(c1s1_joined_bytes != NULL);
  1034 + SrsAutoFree(char, c1s1_joined_bytes, true);
  1035 +
  1036 + digest = new char[OpensslHashSize];
  1037 + if ((ret = openssl_HMACsha256(c1s1_joined_bytes, 1536 - 32, SrsGenuineFPKey, 30, digest)) != ERROR_SUCCESS) {
  1038 + srs_error("calc digest for c1 failed. ret=%d", ret);
  1039 + return ret;
  1040 + }
  1041 + srs_verbose("digest calculated for c1");
  1042 +
  1043 + return ret;
  1044 +}
  1045 +
  1046 +void c1s1::destroy_blocks()
  1047 +{
  1048 + if (schema == srs_schema_invalid) {
  1049 + return;
  1050 + }
  1051 +
  1052 + if (schema == srs_schema0) {
  1053 + srs_key_block_free(&block0.key);
  1054 + srs_digest_block_free(&block1.digest);
  1055 + } else {
  1056 + srs_digest_block_free(&block0.digest);
  1057 + srs_key_block_free(&block1.key);
  1058 + }
  1059 +}
  1060 +
  1061 +SrsComplexHandshake::SrsComplexHandshake()
  1062 +{
  1063 +}
  1064 +
  1065 +SrsComplexHandshake::~SrsComplexHandshake()
  1066 +{
  1067 +}
159 1068
160 int SrsComplexHandshake::handshake(SrsSocket& skt, char* _c1) 1069 int SrsComplexHandshake::handshake(SrsSocket& skt, char* _c1)
161 { 1070 {
162 int ret = ERROR_SUCCESS; 1071 int ret = ERROR_SUCCESS;
163 1072
  1073 + ssize_t nsize;
  1074 +
164 static bool _random_initialized = false; 1075 static bool _random_initialized = false;
165 if (!_random_initialized) { 1076 if (!_random_initialized) {
166 srand(0); 1077 srand(0);
@@ -168,7 +1079,65 @@ int SrsComplexHandshake::handshake(SrsSocket& skt, char* _c1) @@ -168,7 +1079,65 @@ int SrsComplexHandshake::handshake(SrsSocket& skt, char* _c1)
168 srs_trace("srand initialized the random."); 1079 srs_trace("srand initialized the random.");
169 } 1080 }
170 1081
  1082 + // decode c1
171 c1s1 c1; 1083 c1s1 c1;
  1084 + // try schema0.
  1085 + if ((ret = c1.c1_parse(_c1, srs_schema0)) != ERROR_SUCCESS) {
  1086 + srs_error("parse c1 schema%d error. ret=%d", srs_schema0, ret);
  1087 + return ret;
  1088 + }
  1089 + // try schema1
  1090 + bool is_valid = false;
  1091 + if ((ret = c1.c1_validate_digest(is_valid)) != ERROR_SUCCESS || !is_valid) {
  1092 + if ((ret = c1.c1_parse(_c1, srs_schema1)) != ERROR_SUCCESS) {
  1093 + srs_error("parse c1 schema%d error. ret=%d", srs_schema1, ret);
  1094 + return ret;
  1095 + }
  1096 +
  1097 + if ((ret = c1.c1_validate_digest(is_valid)) != ERROR_SUCCESS || !is_valid) {
  1098 + ret = ERROR_RTMP_TRY_SIMPLE_HS;
  1099 + srs_info("all schema valid failed, try simple handshake. ret=%d", ret);
  1100 + return ret;
  1101 + }
  1102 + }
  1103 + srs_verbose("decode c1 success.");
  1104 +
  1105 + // encode s1
  1106 + c1s1 s1;
  1107 + if ((ret = s1.s1_create(&c1)) != ERROR_SUCCESS) {
  1108 + srs_error("create s1 from c1 failed. ret=%d", ret);
  1109 + return ret;
  1110 + }
  1111 + srs_verbose("create s1 from c1 success.");
  1112 +
  1113 + c2s2 s2;
  1114 + if ((ret = s2.s2_create(&c1)) != ERROR_SUCCESS) {
  1115 + srs_error("create s2 from c1 failed. ret=%d", ret);
  1116 + return ret;
  1117 + }
  1118 + srs_verbose("create s2 from c1 success.");
  1119 +
  1120 + // sendout s0s1s2
  1121 + char* s0s1s2 = new char[3073];
  1122 + SrsAutoFree(char, s0s1s2, true);
  1123 + // plain text required.
  1124 + s0s1s2[0] = 0x03;
  1125 + s1.dump(s0s1s2 + 1);
  1126 + s2.dump(s0s1s2 + 1537);
  1127 + if ((ret = skt.write(s0s1s2, 3073, &nsize)) != ERROR_SUCCESS) {
  1128 + srs_warn("complex handshake send s0s1s2 failed. ret=%d", ret);
  1129 + return ret;
  1130 + }
  1131 + srs_verbose("complex handshake send s0s1s2 success.");
  1132 +
  1133 + // recv c2
  1134 + char* c2 = new char[1536];
  1135 + SrsAutoFree(char, c2, true);
  1136 + if ((ret = skt.read_fully(c2, 1536, &nsize)) != ERROR_SUCCESS) {
  1137 + srs_warn("complex handshake read c2 failed. ret=%d", ret);
  1138 + return ret;
  1139 + }
  1140 + srs_verbose("complex handshake read c2 success.");
172 1141
173 return ret; 1142 return ret;
174 } 1143 }
@@ -36,6 +36,7 @@ class SrsSocket; @@ -36,6 +36,7 @@ class SrsSocket;
36 * rtmp complex handshake, 36 * rtmp complex handshake,
37 * @see also crtmp(crtmpserver) or librtmp, 37 * @see also crtmp(crtmpserver) or librtmp,
38 * @see also: http://blog.csdn.net/win_lin/article/details/13006803 38 * @see also: http://blog.csdn.net/win_lin/article/details/13006803
  39 +* @doc update the README.cmd
39 */ 40 */
40 class SrsComplexHandshake 41 class SrsComplexHandshake
41 { 42 {
@@ -63,10 +63,39 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -63,10 +63,39 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
63 #define ERROR_RTMP_AMF0_ENCODE 309 63 #define ERROR_RTMP_AMF0_ENCODE 309
64 #define ERROR_RTMP_CHUNK_SIZE 310 64 #define ERROR_RTMP_CHUNK_SIZE 310
65 #define ERROR_RTMP_TRY_SIMPLE_HS 311 65 #define ERROR_RTMP_TRY_SIMPLE_HS 311
  66 +#define ERROR_RTMP_CH_SCHEMA 312
66 67
67 #define ERROR_SYSTEM_STREAM_INIT 400 68 #define ERROR_SYSTEM_STREAM_INIT 400
68 #define ERROR_SYSTEM_PACKET_INVALID 401 69 #define ERROR_SYSTEM_PACKET_INVALID 401
69 #define ERROR_SYSTEM_CLIENT_INVALID 402 70 #define ERROR_SYSTEM_CLIENT_INVALID 402
70 #define ERROR_SYSTEM_ASSERT_FAILED 403 71 #define ERROR_SYSTEM_ASSERT_FAILED 403
71 72
  73 +// see librtmp.
  74 +// failed when open ssl create the dh
  75 +#define ERROR_OpenSslCreateDH 500
  76 +// failed when open ssl create the Private key.
  77 +#define ERROR_OpenSslCreateP 501
  78 +// when open ssl create G.
  79 +#define ERROR_OpenSslCreateG 502
  80 +// when open ssl parse P1024
  81 +#define ERROR_OpenSslParseP1024 503
  82 +// when open ssl set G
  83 +#define ERROR_OpenSslSetG 504
  84 +// when open ssl generate DHKeys
  85 +#define ERROR_OpenSslGenerateDHKeys 505
  86 +// when open ssl share key already computed.
  87 +#define ERROR_OpenSslShareKeyComputed 506
  88 +// when open ssl get shared key size.
  89 +#define ERROR_OpenSslGetSharedKeySize 507
  90 +// when open ssl get peer public key.
  91 +#define ERROR_OpenSslGetPeerPublicKey 508
  92 +// when open ssl compute shared key.
  93 +#define ERROR_OpenSslComputeSharedKey 509
  94 +// when open ssl is invalid DH state.
  95 +#define ERROR_OpenSslInvalidDHState 510
  96 +// when open ssl copy key
  97 +#define ERROR_OpenSslCopyKey 511
  98 +// when open ssl sha256 digest key invalid size.
  99 +#define ERROR_OpenSslSha256DigestSize 512
  100 +
72 #endif 101 #endif
@@ -345,6 +345,7 @@ public: @@ -345,6 +345,7 @@ public:
345 * shared ptr message. 345 * shared ptr message.
346 * for audio/video/data message that need less memory copy. 346 * for audio/video/data message that need less memory copy.
347 * and only for output. 347 * and only for output.
  348 +* @doc update the README.cmd
348 */ 349 */
349 class SrsSharedPtrMessage : public ISrsMessage 350 class SrsSharedPtrMessage : public ISrsMessage
350 { 351 {
@@ -210,18 +210,18 @@ int SrsRtmp::handshake() @@ -210,18 +210,18 @@ int SrsRtmp::handshake()
210 // plain text required. 210 // plain text required.
211 s0s1s2[0] = 0x03; 211 s0s1s2[0] = 0x03;
212 if ((ret = skt.write(s0s1s2, 3073, &nsize)) != ERROR_SUCCESS) { 212 if ((ret = skt.write(s0s1s2, 3073, &nsize)) != ERROR_SUCCESS) {
213 - srs_warn("send s0s1s2 failed. ret=%d", ret); 213 + srs_warn("simple handshake send s0s1s2 failed. ret=%d", ret);
214 return ret; 214 return ret;
215 } 215 }
216 - srs_verbose("send s0s1s2 success."); 216 + srs_verbose("simple handshake send s0s1s2 success.");
217 217
218 char* c2 = new char[1536]; 218 char* c2 = new char[1536];
219 SrsAutoFree(char, c2, true); 219 SrsAutoFree(char, c2, true);
220 if ((ret = skt.read_fully(c2, 1536, &nsize)) != ERROR_SUCCESS) { 220 if ((ret = skt.read_fully(c2, 1536, &nsize)) != ERROR_SUCCESS) {
221 - srs_warn("read c2 failed. ret=%d", ret); 221 + srs_warn("simple handshake read c2 failed. ret=%d", ret);
222 return ret; 222 return ret;
223 } 223 }
224 - srs_verbose("read c2 success."); 224 + srs_verbose("simple handshake read c2 success.");
225 225
226 srs_trace("simple handshake success."); 226 srs_trace("simple handshake success.");
227 227
@@ -68,6 +68,7 @@ public: @@ -68,6 +68,7 @@ public:
68 private: 68 private:
69 /** 69 /**
70 * detect the time jitter and correct it. 70 * detect the time jitter and correct it.
  71 + * @doc update the README.cmd
71 */ 72 */
72 virtual int jitter_correct(SrsSharedPtrMessage* msg); 73 virtual int jitter_correct(SrsSharedPtrMessage* msg);
73 }; 74 };