public void Login(Cluster cluster, Connection conn, out byte[] sessionToken, out DateTime?sessionExpiration) { sessionToken = null; sessionExpiration = null; dataOffset = 8; conn.SetTimeout(cluster.loginTimeout); try { if (cluster.authMode == AuthMode.INTERNAL) { WriteHeader(LOGIN, 2); WriteField(USER, cluster.user); WriteField(CREDENTIAL, cluster.passwordHash); } else { WriteHeader(LOGIN, 3); WriteField(USER, cluster.user); WriteField(CREDENTIAL, cluster.passwordHash); WriteField(CLEAR_PASSWORD, cluster.password); } WriteSize(); conn.Write(dataBuffer, dataOffset); conn.ReadFully(dataBuffer, HEADER_SIZE); int result = dataBuffer[RESULT_CODE]; if (result != 0) { if (result == INVALID_COMMAND) { // New login not supported. Try old authentication. AuthenticateOld(cluster, conn); return; } // login failed. throw new AerospikeException(result, "Login failed"); } // Read session token. long size = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)) - HEADER_REMAINING; int fieldCount = dataBuffer[11]; if (receiveSize <= 0 || receiveSize > dataBuffer.Length || fieldCount <= 0) { throw new AerospikeException(result, "Failed to retrieve session token"); } conn.ReadFully(dataBuffer, receiveSize); dataOffset = 0; for (int i = 0; i < fieldCount; i++) { int len = ByteUtil.BytesToInt(dataBuffer, dataOffset); dataOffset += 4; int id = dataBuffer[dataOffset++]; len--; if (id == SESSION_TOKEN) { sessionToken = new byte[len]; Array.Copy(dataBuffer, dataOffset, sessionToken, 0, len); } else if (id == SESSION_TTL) { // Subtract 60 seconds from ttl so client session expires before server session. long seconds = ByteUtil.BytesToUInt(dataBuffer, dataOffset) - 60; if (seconds > 0) { sessionExpiration = DateTime.UtcNow.AddSeconds(seconds); } else { Log.Warn("Invalid session TTL: " + seconds); } } dataOffset += len; } if (sessionToken == null) { throw new AerospikeException(result, "Failed to retrieve session token"); } } finally { conn.SetTimeout(cluster.connectionTimeout); } }