{
SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
SilcClient client = (SilcClient)ske->user_data;
- SilcSKEStatus status = SILC_SKE_STATUS_OK;
- char *cp;
- int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
-
- /* Check for initial version string. Allowed "SILC-1.x-". */
- if (!strstr(version, "SILC-1."))
- status = SILC_SKE_STATUS_BAD_VERSION;
-
- /* Check software version */
-
- cp = version + 9;
- if (!cp)
- status = SILC_SKE_STATUS_BAD_VERSION;
+ SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
- maj = atoi(cp);
- cp = strchr(cp, '.');
- if (cp) {
- min = atoi(cp + 1);
- cp++;
- }
- cp = strchr(cp, '.');
- if (cp)
- build = atoi(cp + 1);
-
- cp = client->internal->silc_client_version + 9;
- if (!cp)
- status = SILC_SKE_STATUS_BAD_VERSION;
-
- maj2 = atoi(cp);
- cp = strchr(cp, '.');
- if (cp) {
- min2 = atoi(cp + 1);
- cp++;
+ if (!silc_parse_version_string(version, &r_protocol_version, NULL, NULL,
+ NULL, NULL)) {
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "We don't support server version `%s'",
+ version);
+ return SILC_SKE_STATUS_BAD_VERSION;
}
- cp = strchr(cp, '.');
- if (cp)
- build2 = atoi(cp + 1);
- if (maj != maj2)
- status = SILC_SKE_STATUS_BAD_VERSION;
+ if (!silc_parse_version_string(client->internal->silc_client_version,
+ &l_protocol_version, NULL, NULL,
+ NULL, NULL)) {
+ client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ "We don't support server version `%s'",
+ version);
+ return SILC_SKE_STATUS_BAD_VERSION;
+ }
- if (status != SILC_SKE_STATUS_OK)
+ /* If remote is too new, don't connect */
+ if (l_protocol_version < r_protocol_version) {
client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
"We don't support server version `%s'",
version);
+ return SILC_SKE_STATUS_BAD_VERSION;
+ }
+
+ ske->sock->version = r_protocol_version;
- return status;
+ return SILC_SKE_STATUS_OK;
}
/* Callback that is called by the SKE to indicate that it is safe to
* Reference counter. When allocated it is set to one (1) and it won't
* be freed until it hits zero (0).
*
- * char *hostname
- * char *ip
- * SilcUInt16 port
+ * SilcSocketConnectionHB hb
*
- * Resolved hostname, IP address and port of the connection who owns
- * this object.
+ * The heartbeat context. If NULL, heartbeat is not performed.
*
* SilcBuffer inbuf
* SilcBuffer outbuf
* inbuf buffer and outgoing data after encryption is put to the outbuf
* buffer.
*
- * SilcSocketConnectionHB hb
+ * char *hostname
+ * char *ip
+ * SilcUInt16 port
*
- * The heartbeat context. If NULL, heartbeat is not performed.
+ * Resolved hostname, IP address and port of the connection who owns
+ * this object.
*
***/
struct SilcSocketConnectionStruct {
void *user_data;
SilcProtocol protocol;
SilcUInt32 flags;
- SilcUInt8 sock_error;
int users;
- char *hostname;
- char *ip;
- SilcUInt16 port;
+ SilcSocketConnectionHB hb;
SilcBuffer inbuf;
SilcBuffer outbuf;
- SilcSocketConnectionHB hb;
+ char *hostname;
+ char *ip;
+ SilcUInt16 port;
+ SilcUInt8 sock_error;
+ SilcUInt8 version;
};
/* Macros */
+/* Check for specific protocol version */
+#define SILC_PROTOCOL_VERSION(s, maj, min) (s->version == maj##min)
+
/* Amount of bytes to be read from the socket connection at once. */
#define SILC_SOCKET_READ_SIZE 16384