diff --git a/SAM.cpp b/SAM.cpp index b94f9e0d..7da8ff68 100644 --- a/SAM.cpp +++ b/SAM.cpp @@ -86,12 +86,39 @@ namespace client { m_Buffer[bytes_transferred] = 0; LogPrint ("SAM handshake ", m_Buffer); - if (!memcmp (m_Buffer, SAM_HANDSHAKE, strlen (SAM_HANDSHAKE))) + char * separator = strchr (m_Buffer, ' '); + if (separator) { - // TODO: check version - boost::asio::async_write (m_Socket, boost::asio::buffer (SAM_HANDSHAKE_REPLY, strlen (SAM_HANDSHAKE_REPLY)), boost::asio::transfer_all (), - std::bind(&SAMSocket::HandleHandshakeReplySent, shared_from_this (), - std::placeholders::_1, std::placeholders::_2)); + separator = strchr (separator + 1, ' '); + if (separator) + *separator = 0; + } + + if (!strcmp (m_Buffer, SAM_HANDSHAKE)) + { + std::string version("3.0"); + // try to find MIN and MAX, 3.0 if not found + if (separator) + { + separator++; + std::map params; + ExtractParams (separator, bytes_transferred - (separator - m_Buffer), params); + auto it = params.find (SAM_PARAM_MAX); + // TODO: check MIN as well + if (it != params.end ()) + version = it->second; + } + if (version[0] == '3') // we support v3 (3.0 and 3.1) only + { +#ifdef _MSC_VER + size_t l = sprintf_s (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); +#else + size_t l = snprintf (m_Buffer, SAM_SOCKET_BUFFER_SIZE, SAM_HANDSHAKE_REPLY, version.c_str ()); +#endif + SendMessageReply (m_Buffer, l, false); + } + else + SendMessageReply (SAM_HANDSHAKE_I2P_ERROR, strlen (SAM_HANDSHAKE_I2P_ERROR), true); } else { diff --git a/SAM.h b/SAM.h index b632028d..78de49ce 100644 --- a/SAM.h +++ b/SAM.h @@ -24,7 +24,8 @@ namespace client const int SAM_NAMING_LOOKUP_TIMEOUT = 5; // in seconds const int SAM_SESSION_READINESS_CHECK_INTERVAL = 20; // in seconds const char SAM_HANDSHAKE[] = "HELLO VERSION"; - const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=3.0\n"; + const char SAM_HANDSHAKE_REPLY[] = "HELLO REPLY RESULT=OK VERSION=%s\n"; + const char SAM_HANDSHAKE_I2P_ERROR[] = "HELLO REPLY RESULT=I2P_ERROR\n"; const char SAM_SESSION_CREATE[] = "SESSION CREATE"; const char SAM_SESSION_CREATE_REPLY_OK[] = "SESSION STATUS RESULT=OK DESTINATION=%s\n"; const char SAM_SESSION_CREATE_DUPLICATED_ID[] = "SESSION STATUS RESULT=DUPLICATED_ID\n"; @@ -42,7 +43,9 @@ namespace client const char SAM_NAMING_REPLY[] = "NAMING REPLY RESULT=OK NAME=ME VALUE=%s\n"; const char SAM_DATAGRAM_RECEIVED[] = "DATAGRAM_RECEIVED DESTINATION=%s SIZE=%lu\n"; const char SAM_NAMING_REPLY_INVALID_KEY[] = "NAMING REPLY RESULT=INVALID_KEY NAME=%s\n"; - const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; + const char SAM_NAMING_REPLY_KEY_NOT_FOUND[] = "NAMING REPLY RESULT=INVALID_KEY_NOT_FOUND NAME=%s\n"; + const char SAM_PARAM_MIN[] = "MIN"; + const char SAM_PARAM_MAX[] = "MAX"; const char SAM_PARAM_STYLE[] = "STYLE"; const char SAM_PARAM_ID[] = "ID"; const char SAM_PARAM_SILENT[] = "SILENT";