| 419 | } |
| 420 | |
| 421 | void TNonblockingServer::TConnection::workSocket() { |
| 422 | while (true) { |
| 423 | int got = 0, left = 0, sent = 0; |
| 424 | uint32_t fetch = 0; |
| 425 | |
| 426 | switch (socketState_) { |
| 427 | case SOCKET_RECV_FRAMING: |
| 428 | union { |
| 429 | uint8_t buf[sizeof(uint32_t)]; |
| 430 | uint32_t size; |
| 431 | } framing; |
| 432 | |
| 433 | // if we've already received some bytes we kept them here |
| 434 | framing.size = readWant_; |
| 435 | // determine size of this frame |
| 436 | try { |
| 437 | // Read from the socket |
| 438 | fetch = tSocket_->read(&framing.buf[readBufferPos_], |
| 439 | uint32_t(sizeof(framing.size) - readBufferPos_)); |
| 440 | if (fetch == 0) { |
| 441 | // Whenever we get here it means a remote disconnect |
| 442 | close(); |
| 443 | return; |
| 444 | } |
| 445 | readBufferPos_ += fetch; |
| 446 | } catch (TTransportException& te) { |
| 447 | //In Nonblocking SSLSocket some operations need to be retried again. |
| 448 | //Current approach is parsing exception message, but a better solution needs to be investigated. |
| 449 | if(!strstr(te.what(), "retry")) { |
| 450 | TOutput::instance().printf("TConnection::workSocket(): %s", te.what()); |
| 451 | close(); |
| 452 | |
| 453 | return; |
| 454 | } |
| 455 | } |
| 456 | |
| 457 | if (readBufferPos_ < sizeof(framing.size)) { |
| 458 | // more needed before frame size is known -- save what we have so far |
| 459 | readWant_ = framing.size; |
| 460 | return; |
| 461 | } |
| 462 | |
| 463 | readWant_ = ntohl(framing.size); |
| 464 | if (readWant_ > server_->getMaxFrameSize()) { |
| 465 | // Don't allow giant frame sizes. This prevents bad clients from |
| 466 | // causing us to try and allocate a giant buffer. |
| 467 | TOutput::instance().printf( |
| 468 | "TNonblockingServer: frame size too large " |
| 469 | "(%" PRIu32 " > %" PRIu64 |
| 470 | ") from client %s. " |
| 471 | "Remote side not using TFramedTransport?", |
| 472 | readWant_, |
| 473 | (uint64_t)server_->getMaxFrameSize(), |
| 474 | tSocket_->getSocketInfo().c_str()); |
| 475 | close(); |
| 476 | return; |
| 477 | } |
| 478 | // size known; now get the rest of the frame |
no test coverage detected