| 1173 | } |
| 1174 | |
| 1175 | ParseResult RtmpContext::WaitForC0C1orSimpleRtmp(butil::IOBuf* source, Socket* socket) { |
| 1176 | if (source->length() < RTMP_HANDSHAKE_SIZE0 + MAGIC_NUMBER_SIZE) { |
| 1177 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 1178 | } |
| 1179 | char buf[RTMP_HANDSHAKE_SIZE0 + MAGIC_NUMBER_SIZE]; |
| 1180 | const char* p = (const char*)source->fetch(buf, sizeof(buf)); |
| 1181 | if (memcmp(p + RTMP_HANDSHAKE_SIZE0, SIMPLIFIED_RTMP_MAGIC_NUMBER, MAGIC_NUMBER_SIZE) == 0) { |
| 1182 | source->pop_front(RTMP_HANDSHAKE_SIZE0 + MAGIC_NUMBER_SIZE); |
| 1183 | SetState(socket->remote_side(), STATE_RECEIVED_C2); |
| 1184 | _simplified_rtmp = true; |
| 1185 | return OnChunks(source, socket); |
| 1186 | } |
| 1187 | |
| 1188 | if (source->length() < RTMP_HANDSHAKE_SIZE0 + RTMP_HANDSHAKE_SIZE1) { |
| 1189 | return MakeParseError(PARSE_ERROR_NOT_ENOUGH_DATA); |
| 1190 | } |
| 1191 | // Consume C0C1 and change the state. |
| 1192 | char c0c1_buf[RTMP_HANDSHAKE_SIZE0 + RTMP_HANDSHAKE_SIZE1]; |
| 1193 | source->cutn(c0c1_buf, sizeof(c0c1_buf)); |
| 1194 | SetState(socket->remote_side(), STATE_RECEIVED_C0C1); |
| 1195 | |
| 1196 | butil::IOBuf tmp; |
| 1197 | adobe_hs::C1 c1; |
| 1198 | if (c1.Load(c0c1_buf + RTMP_HANDSHAKE_SIZE0)) { |
| 1199 | RPC_VLOG << socket->remote_side() << ": Loaded C1 with schema" |
| 1200 | << (c1.schema() == adobe_hs::SCHEMA0 ? "0" : "1"); |
| 1201 | tmp.push_back(RTMP_DEFAULT_VERSION); |
| 1202 | { |
| 1203 | adobe_hs::S1 s1; |
| 1204 | if (!s1.Generate(c1)) { |
| 1205 | LOG(WARNING) << socket->remote_side() << ": Fail to generate s1"; |
| 1206 | return MakeParseError(PARSE_ERROR_NO_RESOURCE); |
| 1207 | } |
| 1208 | char buf[RTMP_HANDSHAKE_SIZE1]; |
| 1209 | s1.Save(buf); |
| 1210 | tmp.append(buf, RTMP_HANDSHAKE_SIZE1); |
| 1211 | _s1_digest = malloc(adobe_hs::DigestBlock::DIGEST_SIZE); |
| 1212 | if (_s1_digest == NULL) { |
| 1213 | LOG(ERROR) << "Fail to malloc"; |
| 1214 | return MakeParseError(PARSE_ERROR_NO_RESOURCE); |
| 1215 | } |
| 1216 | memcpy(_s1_digest, s1.digest_blk.digest(), |
| 1217 | adobe_hs::DigestBlock::DIGEST_SIZE); |
| 1218 | } |
| 1219 | { |
| 1220 | adobe_hs::S2 s2; |
| 1221 | if (!s2.Generate(c1.digest_blk.digest())) { |
| 1222 | LOG(ERROR) << socket->remote_side() << ": Fail to generate s2"; |
| 1223 | return MakeParseError(PARSE_ERROR_NO_RESOURCE); |
| 1224 | } |
| 1225 | char buf[RTMP_HANDSHAKE_SIZE2]; |
| 1226 | s2.Save(buf); |
| 1227 | tmp.append(buf, RTMP_HANDSHAKE_SIZE2); |
| 1228 | } |
| 1229 | } else { |
| 1230 | RPC_VLOG << socket->remote_side() << ": Fallback to simple handshaking"; |
| 1231 | // Send back S0 S1 S2 |
| 1232 | char buf[9]; |
nothing calls this directly
no test coverage detected