in c/src/core/autodetect.c [80:121]
pni_protocol_type_t pni_sniff_header(const char *buf, size_t len)
{
if (len < 3) return PNI_PROTOCOL_INSUFFICIENT;
bool isSSL3Handshake = buf[0]==22 && // handshake
buf[1]==3 && buf[2]<=3; // SSL 3.0 & TLS 1.0-1.2 (v3.1-3.3)
if (isSSL3Handshake) return PNI_PROTOCOL_SSL;
bool isFirst3AMQP = buf[0]=='A' && buf[1]=='M' && buf[2]=='Q';
bool isFirst3SSL2CLientHello = buf[2]==1; // Client Hello
if (!isFirst3AMQP && !isFirst3SSL2CLientHello) return PNI_PROTOCOL_UNKNOWN;
if (len < 4) return PNI_PROTOCOL_INSUFFICIENT;
bool isAMQP = isFirst3AMQP && buf[3]=='P';
bool isFirst4SSL2ClientHello = isFirst3SSL2CLientHello && (buf[3]==2 || buf[3]==3);
if (!isAMQP && !isFirst4SSL2ClientHello) return PNI_PROTOCOL_UNKNOWN;
if (len < 5) return PNI_PROTOCOL_INSUFFICIENT;
bool isSSL2Handshake = buf[2] == 1 && // MSG-CLIENT-HELLO
((buf[3] == 3 && buf[4] <= 3) || // SSL 3.0 & TLS 1.0-1.2 (v3.1-3.3)
(buf[3] == 2 && buf[4] == 0)); // SSL 2
if (isSSL2Handshake) return PNI_PROTOCOL_SSL;
bool isFirst5OldAMQP = isAMQP && buf[4]==1;
bool isFirst5AMQP = isAMQP && (buf[4]==0 || buf[4]==2 || buf[4]==3);
if (!isFirst5AMQP && !isFirst5OldAMQP) return PNI_PROTOCOL_UNKNOWN;
if (len < 6) return PNI_PROTOCOL_INSUFFICIENT;
// Both old and new versions of AMQP have 1 in byte 5
if (buf[5]!=1) return PNI_PROTOCOL_UNKNOWN;
// From here on it must be some sort of AMQP
if (len < 8) return PNI_PROTOCOL_INSUFFICIENT;
if (buf[6]==0 && buf[7]==0) {
// AM<QP 1.0
if (buf[4]==0) return PNI_PROTOCOL_AMQP1;
if (buf[4]==2) return PNI_PROTOCOL_AMQP_SSL;
if (buf[4]==3) return PNI_PROTOCOL_AMQP_SASL;
}
return PNI_PROTOCOL_AMQP_OTHER;
}