MCPcopy Create free account
hub / github.com/3rdparty/libprocess / peek_callback

Method peek_callback

src/posix/libevent/libevent_ssl_socket.cpp:1027–1095  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1025
1026
1027void LibeventSSLSocketImpl::peek_callback(
1028 evutil_socket_t fd,
1029 short what,
1030 void* arg)
1031{
1032 CHECK(__in_event_loop__);
1033
1034 CHECK(what & EV_READ);
1035 char data[6];
1036
1037 // Try to peek the first 6 bytes of the message.
1038 ssize_t size = ::recv(fd, data, 6, MSG_PEEK);
1039
1040 // Based on the function 'ssl23_get_client_hello' in openssl, we
1041 // test whether to dispatch to the SSL or non-SSL based accept based
1042 // on the following rules:
1043 // 1. If there are fewer than 3 bytes: non-SSL.
1044 // 2. If the 1st bit of the 1st byte is set AND the 3rd byte is
1045 // equal to SSL2_MT_CLIENT_HELLO: SSL.
1046 // 3. If the 1st byte is equal to SSL3_RT_HANDSHAKE AND the 2nd
1047 // byte is equal to SSL3_VERSION_MAJOR and the 6th byte is
1048 // equal to SSL3_MT_CLIENT_HELLO: SSL.
1049 // 4. Otherwise: non-SSL.
1050
1051 // For an ascii based protocol to falsely get dispatched to SSL it
1052 // needs to:
1053 // 1. Start with an invalid ascii character (0x80).
1054 // 2. OR have the first 2 characters be a SYN followed by ETX, and
1055 // then the 6th character be SOH.
1056 // These conditions clearly do not constitute valid HTTP requests,
1057 // and are unlikely to collide with other existing protocols.
1058
1059 bool ssl = false; // Default to rule 4.
1060
1061 if (size < 2) { // Rule 1.
1062 ssl = false;
1063 } else if ((data[0] & 0x80) && data[2] == SSL2_MT_CLIENT_HELLO) { // Rule 2.
1064 ssl = true;
1065 } else if (data[0] == SSL3_RT_HANDSHAKE &&
1066 data[1] == SSL3_VERSION_MAJOR &&
1067 data[5] == SSL3_MT_CLIENT_HELLO) { // Rule 3.
1068 ssl = true;
1069 }
1070
1071 AcceptRequest* request = reinterpret_cast<AcceptRequest*>(arg);
1072
1073 // We call 'event_free()' here because it ensures the event is made
1074 // non-pending and inactive before it gets deallocated.
1075 event_free(request->peek_event);
1076 request->peek_event = nullptr;
1077
1078 if (ssl) {
1079 accept_SSL_callback(request);
1080 } else {
1081 // Downgrade to a non-SSL socket implementation.
1082 //
1083 // NOTE: The `int_fd` must be explicitly constructed to avoid the
1084 // `intptr_t` being casted to an `int`, resulting in a `HANDLE`

Callers

nothing calls this directly

Calls 4

recvFunction · 0.85
failMethod · 0.45
setMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected