| 1270 | } |
| 1271 | |
| 1272 | ParseResult RtmpContext::WaitForS0S1(butil::IOBuf* source, Socket* socket) { |
| 1273 | if (source->length() < RTMP_HANDSHAKE_SIZE0 + RTMP_HANDSHAKE_SIZE1) { |
| 1274 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 1275 | } |
| 1276 | // Consume S0 S1 and change the state. |
| 1277 | char s0s1_buf[RTMP_HANDSHAKE_SIZE0 + RTMP_HANDSHAKE_SIZE1]; |
| 1278 | source->cutn(s0s1_buf, sizeof(s0s1_buf)); |
| 1279 | SetState(socket->remote_side(), STATE_RECEIVED_S0S1); |
| 1280 | |
| 1281 | butil::IOBuf tmp; |
| 1282 | bool done_adobe_hs = false; |
| 1283 | if (!_only_check_simple_s0s1) { |
| 1284 | adobe_hs::S1 s1; |
| 1285 | if (s1.Load(s0s1_buf + RTMP_HANDSHAKE_SIZE0, adobe_hs::SCHEMA1)) { |
| 1286 | RPC_VLOG << socket->remote_side() << ": Loaded S1 with schema1"; |
| 1287 | adobe_hs::C2 c2; |
| 1288 | if (!c2.Generate(s1.digest_blk.digest())) { |
| 1289 | LOG(ERROR) << socket->remote_side() << ": Fail to generate c2"; |
| 1290 | return MakeParseError(PARSE_ERROR_NO_RESOURCE); |
| 1291 | } |
| 1292 | c2.Save(s0s1_buf + RTMP_HANDSHAKE_SIZE0); |
| 1293 | tmp.append(s0s1_buf + RTMP_HANDSHAKE_SIZE0, RTMP_HANDSHAKE_SIZE1); |
| 1294 | done_adobe_hs = true; |
| 1295 | } else { |
| 1296 | RPC_VLOG << socket->remote_side() << ": Fallback to simple handshaking"; |
| 1297 | } |
| 1298 | } |
| 1299 | if (!done_adobe_hs) { |
| 1300 | // Send back C2 |
| 1301 | char* const c2 = s0s1_buf + RTMP_HANDSHAKE_SIZE0; |
| 1302 | char* q = c2 + 4; // skip time |
| 1303 | const uint32_t c2_time2 = GetRtmpTimestamp(); |
| 1304 | WriteBigEndian4Bytes(&q, c2_time2); // time2 |
| 1305 | tmp.append(c2, RTMP_HANDSHAKE_SIZE2); |
| 1306 | } |
| 1307 | if (WriteAll(socket->fd(), &tmp) != 0) { |
| 1308 | LOG(WARNING) << socket->remote_side() << ": Fail to write C2"; |
| 1309 | return MakeParseError(PARSE_ERROR_NO_RESOURCE); |
| 1310 | } |
| 1311 | return WaitForS2(source, socket); |
| 1312 | } |
| 1313 | |
| 1314 | ParseResult RtmpContext::WaitForS2(butil::IOBuf* source, Socket* socket) { |
| 1315 | if (source->length() < RTMP_HANDSHAKE_SIZE2) { |
nothing calls this directly
no test coverage detected