//------------------------------------------------------- // Private methods. //------------------------------------------------------- /// <summary> /// Issue request and set results buffer. This method is used internally. /// The static request methods should be used instead. /// </summary> /// <param name="conn">socket connection to server node</param> /// <exception cref="AerospikeException">if socket send or receive fails</exception> private void SendCommand(Connection conn) { try { // Write size field. ulong size = ((ulong)offset - 8L) | (2L << 56) | (1L << 48); ByteUtil.LongToBytes(size, buffer, 0); // Write. conn.Write(buffer, offset); // Read - reuse input buffer. conn.ReadFully(buffer, 8); size = (ulong)ByteUtil.BytesToLong(buffer, 0); length = (int)(size & 0xFFFFFFFFFFFFL); ResizeBuffer(length); conn.ReadFully(buffer, length); offset = 0; } catch (SocketException se) { throw new AerospikeException(se); } }
public long GetLongBig(int offset) { if (offset < 0 || offset + 8 > this.length) { return(0); } return(ByteUtil.BytesToLong(bytes, offset)); }
private void ReceiveEvent() { //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader); if (eventArgs.BytesTransferred <= 0) { FailOnNetworkError(new AerospikeException.Connection("Connection closed")); return; } dataOffset += eventArgs.BytesTransferred; if (dataOffset < dataLength) { eventArgs.SetBuffer(dataOffset, dataLength - dataOffset); Receive(); return; } dataOffset = 0; if (inHeader) { dataLength = (int)(ByteUtil.BytesToLong(dataBuffer, 0) & 0xFFFFFFFFFFFFL); if (dataLength <= 0) { ReceiveBegin(); return; } inHeader = false; if (dataLength > dataBuffer.Length) { ResizeBuffer(); } eventArgs.SetBuffer(dataBuffer, dataOffset, dataLength); Receive(); } else { if (inAuthenticate) { inAuthenticate = false; inHeader = true; int resultCode = dataBuffer[1]; if (resultCode != 0) { throw new AerospikeException(resultCode); } ConnectionReady(); return; } ParseCommand(); } }
protected internal override void ParseResult(Connection conn) { // Read header. conn.ReadFully(dataBuffer, MSG_TOTAL_HEADER_SIZE); long sz = ByteUtil.BytesToLong(dataBuffer, 0); byte headerLength = dataBuffer[8]; int resultCode = dataBuffer[13]; int generation = ByteUtil.BytesToInt(dataBuffer, 14); int expiration = ByteUtil.BytesToInt(dataBuffer, 18); int fieldCount = ByteUtil.BytesToShort(dataBuffer, 26); // almost certainly 0 int opCount = ByteUtil.BytesToShort(dataBuffer, 28); int receiveSize = ((int)(sz & 0xFFFFFFFFFFFFL)) - headerLength; // Read remaining message bytes. if (receiveSize > 0) { SizeBuffer(receiveSize); conn.ReadFully(dataBuffer, receiveSize); } if (resultCode == 0) { if (opCount == 0) { // Bin data was not returned. record = new Record(null, generation, expiration); return; } record = ParseRecord(opCount, fieldCount, generation, expiration); return; } if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR) { HandleNotFound(resultCode); return; } if (resultCode == ResultCode.FILTERED_OUT) { if (policy.failOnFilteredOut) { throw new AerospikeException(resultCode); } return; } if (resultCode == ResultCode.UDF_BAD_RESPONSE) { record = ParseRecord(opCount, fieldCount, generation, expiration); HandleUdfError(resultCode); return; } throw new AerospikeException(resultCode); }
protected internal void EmptySocket(Connection conn) { // There should not be any more bytes. // Empty the socket to be safe. long sz = ByteUtil.BytesToLong(dataBuffer, 0); int headerLength = dataBuffer[8]; int receiveSize = ((int)(sz & 0xFFFFFFFFFFFFL)) - headerLength; // Read remaining message bytes. if (receiveSize > 0) { SizeBuffer(receiveSize); conn.ReadFully(dataBuffer, receiveSize); } }
private int ReadBlocks(Connection conn) { int status = 0; while (status == 0) { conn.ReadFully(dataBuffer, 8); long size = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)); if (receiveSize > 0) { if (receiveSize > dataBuffer.Length) { dataBuffer = ThreadLocalData.ResizeBuffer(receiveSize); } conn.ReadFully(dataBuffer, receiveSize); status = ParseBlock(receiveSize); } } return(status); }
protected internal sealed override void ParseResult(Connection conn) { // Read socket into receive buffer one record at a time. Do not read entire receive size // because the thread local receive buffer would be too big. Also, scan callbacks can nest // further database commands which contend with the receive buffer. bconn = new BufferedConnection(conn, 8192); bool status = true; while (status) { // Read header. ReadBytes(8); long size = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = ((int)(size & 0xFFFFFFFFFFFFL)); if (receiveSize > 0) { status = ParseGroup(receiveSize); } } }
protected internal override void ParseResult(Connection conn) { // Read header. conn.ReadFully(dataBuffer, 8); long sz = ByteUtil.BytesToLong(dataBuffer, 0); int receiveSize = (int)(sz & 0xFFFFFFFFFFFFL); if (receiveSize <= 0) { throw new AerospikeException("Invalid receive size: " + receiveSize); } SizeBuffer(receiveSize); conn.ReadFully(dataBuffer, receiveSize); conn.UpdateLastUsed(); ulong type = (ulong)((sz >> 48) & 0xff); if (type == Command.AS_MSG_TYPE) { dataOffset = 5; } else if (type == Command.MSG_TYPE_COMPRESSED) { int usize = (int)ByteUtil.BytesToLong(dataBuffer, 0); byte[] ubuf = new byte[usize]; ByteUtil.Decompress(dataBuffer, 8, receiveSize, ubuf, usize); dataBuffer = ubuf; dataOffset = 13; } else { throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE); } int resultCode = dataBuffer[dataOffset]; dataOffset++; int generation = ByteUtil.BytesToInt(dataBuffer, dataOffset); dataOffset += 4; int expiration = ByteUtil.BytesToInt(dataBuffer, dataOffset); dataOffset += 8; int fieldCount = ByteUtil.BytesToShort(dataBuffer, dataOffset); dataOffset += 2; int opCount = ByteUtil.BytesToShort(dataBuffer, dataOffset); dataOffset += 2; if (resultCode == 0) { if (opCount == 0) { // Bin data was not returned. record = new Record(null, generation, expiration); return; } record = ParseRecord(opCount, fieldCount, generation, expiration); return; } if (resultCode == ResultCode.KEY_NOT_FOUND_ERROR) { HandleNotFound(resultCode); return; } if (resultCode == ResultCode.FILTERED_OUT) { if (policy.failOnFilteredOut) { throw new AerospikeException(resultCode); } return; } if (resultCode == ResultCode.UDF_BAD_RESPONSE) { record = ParseRecord(opCount, fieldCount, generation, expiration); HandleUdfError(resultCode); return; } throw new AerospikeException(resultCode); }
internal void ReceiveEvent() { if (eventArgs.BytesTransferred <= 0) { Fail("Connection closed"); return; } dataOffset += eventArgs.BytesTransferred; if (dataOffset < dataLength) { eventArgs.SetBuffer(dataOffset, dataLength - dataOffset); Receive(); return; } dataOffset = 0; if (inHeader) { long proto = ByteUtil.BytesToLong(dataBuffer, dataOffset); int length = (int)(proto & 0xFFFFFFFFFFFFL); if (length <= 0) { ReceiveBegin(); return; } inHeader = false; if (length > dataBuffer.Length) { Fail("Invalid auth response"); return; } eventArgs.SetBuffer(dataOffset, length); dataLength = dataOffset + length; Receive(); } else { int resultCode = dataBuffer[dataOffset + 1]; if (resultCode != 0 && resultCode != ResultCode.SECURITY_NOT_ENABLED) { // Authentication failed. Session token probably expired. // Signal tend thread to perform node login, so future // transactions do not fail. node.SignalLogin(); // This is a rare event because the client tracks session // expiration and will relogin before session expiration. // Do not try to login on same socket because login can take // a long time and thousands of simultaneous logins could // overwhelm server. Fail("Failed to authenticate: " + resultCode); return; } ConnectionReady(); } }
private void ReceiveEvent() { //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader); if (usingSocketTimeout) { eventReceived = true; } if (eventArgs.BytesTransferred <= 0) { ConnectionFailed(new AerospikeException.Connection("Connection closed")); return; } dataOffset += eventArgs.BytesTransferred; if (dataOffset < dataLength) { eventArgs.SetBuffer(dataOffset, dataLength - dataOffset); Receive(); return; } dataOffset = segment.offset; if (inHeader) { int length = (int)(ByteUtil.BytesToLong(dataBuffer, dataOffset) & 0xFFFFFFFFFFFFL); if (length <= 0) { ReceiveBegin(); return; } inHeader = false; if (length > segment.size) { ResizeBuffer(length); dataBuffer = segment.buffer; dataOffset = segment.offset; } eventArgs.SetBuffer(dataBuffer, dataOffset, length); dataLength = dataOffset + length; Receive(); } else { if (inAuthenticate) { inAuthenticate = false; inHeader = true; int resultCode = dataBuffer[dataOffset + 1]; if (resultCode != 0) { // Authentication failed. Session token probably expired. // Signal tend thread to perform node login, so future // transactions do not fail. node.SignalLogin(); // This is a rare event because the client tracks session // expiration and will relogin before session expiration. // Do not try to login on same socket because login can take // a long time and thousands of simultaneous logins could // overwhelm server. throw new AerospikeException(resultCode); } ConnectionReady(); return; } ParseCommand(); } }
private object UnpackObject() { int type = buffer[offset++]; switch (type) { case 0xc0: // nil { return(null); } case 0xc3: // boolean true { return(true); } case 0xc2: // boolean false { return(false); } case 0xca: // float { float val = ByteUtil.BytesToFloat(buffer, offset); offset += 4; return(val); } case 0xcb: // double { double val = ByteUtil.BytesToDouble(buffer, offset); offset += 8; return(val); } case 0xd0: // signed 8 bit integer { return((long)(sbyte)(buffer[offset++])); } case 0xcc: // unsigned 8 bit integer { return((long)(buffer[offset++])); } case 0xd1: // signed 16 bit integer { int val = ByteUtil.BytesToShort(buffer, offset); offset += 2; return((long)(short)val); } case 0xcd: // unsigned 16 bit integer { int val = ByteUtil.BytesToShort(buffer, offset); offset += 2; return((long)val); } case 0xd2: // signed 32 bit integer { int val = ByteUtil.BytesToInt(buffer, offset); offset += 4; return((long)val); } case 0xce: // unsigned 32 bit integer { uint val = ByteUtil.BytesToUInt(buffer, offset); offset += 4; return((long)val); } case 0xd3: // signed 64 bit integer { long val = ByteUtil.BytesToLong(buffer, offset); offset += 8; return(val); } case 0xcf: // unsigned 64 bit integer { // The contract is to always return long. // The caller can always cast back to ulong. long val = ByteUtil.BytesToLong(buffer, offset); offset += 8; return(val); } case 0xda: // raw bytes with 16 bit header { int count = ByteUtil.BytesToShort(buffer, offset); offset += 2; return(UnpackBlob(count)); } case 0xdb: // raw bytes with 32 bit header { // Array length is restricted to positive int values (0 - int.MAX_VALUE). int count = ByteUtil.BytesToInt(buffer, offset); offset += 4; return(UnpackBlob(count)); } case 0xdc: // list with 16 bit header { int count = ByteUtil.BytesToShort(buffer, offset); offset += 2; return(UnpackList(count)); } case 0xdd: // list with 32 bit header { // List size is restricted to positive int values (0 - int.MAX_VALUE). int count = ByteUtil.BytesToInt(buffer, offset); offset += 4; return(UnpackList(count)); } case 0xde: // map with 16 bit header { int count = ByteUtil.BytesToShort(buffer, offset); offset += 2; return(UnpackMap(count)); } case 0xdf: // map with 32 bit header { // Map size is restricted to positive int values (0 - int.MAX_VALUE). int count = ByteUtil.BytesToInt(buffer, offset); offset += 4; return(UnpackMap(count)); } default: { if ((type & 0xe0) == 0xa0) // raw bytes with 8 bit combined header { return(UnpackBlob(type & 0x1f)); } if ((type & 0xf0) == 0x80) // map with 8 bit combined header { return(UnpackMap(type & 0x0f)); } if ((type & 0xf0) == 0x90) // list with 8 bit combined header { return(UnpackList(type & 0x0f)); } if (type < 0x80) // 8 bit combined unsigned integer { return((long)type); } if (type >= 0xe0) // 8 bit combined signed integer { return((long)(type - 0xe0 - 32)); } throw new IOException("Unknown unpack type: " + type); } } }
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); } }
private void ReceiveEvent() { //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader); if (socketWatch != null) { eventReceived = true; } if (eventArgs.BytesTransferred <= 0) { ConnectionFailed(new AerospikeException.Connection("Connection closed")); return; } dataOffset += eventArgs.BytesTransferred; if (dataOffset < dataLength) { eventArgs.SetBuffer(dataOffset, dataLength - dataOffset); Receive(); return; } dataOffset = segment.offset; if (inHeader) { long proto = ByteUtil.BytesToLong(dataBuffer, dataOffset); int length = (int)(proto & 0xFFFFFFFFFFFFL); if (length <= 0) { ReceiveBegin(); return; } compressed = ((proto >> 48) & 0xFF) == (long)Command.MSG_TYPE_COMPRESSED; inHeader = false; if (length > segment.size) { ResizeBuffer(length); dataBuffer = segment.buffer; dataOffset = segment.offset; } eventArgs.SetBuffer(dataBuffer, dataOffset, length); dataLength = dataOffset + length; Receive(); } else { if (inAuthenticate) { inAuthenticate = false; inHeader = true; int resultCode = dataBuffer[dataOffset + 1]; if (resultCode != 0 && resultCode != ResultCode.SECURITY_NOT_ENABLED) { // Authentication failed. Session token probably expired. // Signal tend thread to perform node login, so future // transactions do not fail. node.SignalLogin(); // This is a rare event because the client tracks session // expiration and will relogin before session expiration. // Do not try to login on same socket because login can take // a long time and thousands of simultaneous logins could // overwhelm server. throw new AerospikeException(resultCode); } ConnectionReady(); return; } conn.UpdateLastUsed(); if (compressed) { int usize = (int)ByteUtil.BytesToLong(dataBuffer, dataOffset); dataOffset += 8; byte[] ubuf = new byte[usize]; ByteUtil.Decompress(dataBuffer, dataOffset, dataLength, ubuf, usize); dataBuffer = ubuf; dataOffset = 8; dataLength = usize; } ParseCommand(); } }
private void ReceiveEvent() { //Log.Info("Receive Event: " + eventArgs.BytesTransferred + "," + dataOffset + "," + dataLength + "," + inHeader); if (usingSocketTimeout) { eventReceived = true; } if (eventArgs.BytesTransferred <= 0) { ConnectionFailed(new AerospikeException.Connection("Connection closed")); return; } dataOffset += eventArgs.BytesTransferred; if (dataOffset < dataLength) { eventArgs.SetBuffer(dataOffset, dataLength - dataOffset); Receive(); return; } dataOffset = segment.offset; if (inHeader) { int length = (int)(ByteUtil.BytesToLong(dataBuffer, dataOffset) & 0xFFFFFFFFFFFFL); if (length <= 0) { ReceiveBegin(); return; } inHeader = false; if (length > segment.size) { ResizeBuffer(length); dataBuffer = segment.buffer; dataOffset = segment.offset; } eventArgs.SetBuffer(dataBuffer, dataOffset, length); dataLength = dataOffset + length; Receive(); } else { if (inAuthenticate) { inAuthenticate = false; inHeader = true; int resultCode = dataBuffer[dataOffset + 1]; if (resultCode != 0) { throw new AerospikeException(resultCode); } ConnectionReady(); return; } ParseCommand(); } }
protected internal sealed override void ParseResult(Connection conn) { // Read blocks of records. Do not use thread local receive buffer because each // block will likely be too big for a cache. Also, scan callbacks can nest // further database commands which would contend with the thread local receive buffer. // Instead, use separate heap allocated buffers. byte[] protoBuf = new byte[8]; byte[] buf = null; byte[] ubuf = null; int receiveSize; while (true) { // Read header conn.ReadFully(protoBuf, 8); long proto = ByteUtil.BytesToLong(protoBuf, 0); int size = (int)(proto & 0xFFFFFFFFFFFFL); if (size <= 0) { continue; } // Prepare buffer if (buf == null || size > buf.Length) { // Corrupted data streams can result in a huge length. // Do a sanity check here. if (size > MAX_BUFFER_SIZE) { throw new AerospikeException("Invalid proto size: " + size); } int capacity = (size + 16383) & ~16383; // Round up in 16KB increments. buf = new byte[capacity]; } // Read remaining message bytes in group. conn.ReadFully(buf, size); conn.UpdateLastUsed(); ulong type = (ulong)((proto >> 48) & 0xff); if (type == Command.AS_MSG_TYPE) { dataBuffer = buf; dataOffset = 0; receiveSize = size; } else if (type == Command.MSG_TYPE_COMPRESSED) { int usize = (int)ByteUtil.BytesToLong(buf, 0); if (ubuf == null || usize > ubuf.Length) { if (usize > MAX_BUFFER_SIZE) { throw new AerospikeException("Invalid proto size: " + usize); } int capacity = (usize + 16383) & ~16383; // Round up in 16KB increments. ubuf = new byte[capacity]; } ByteUtil.Decompress(buf, 8, size, ubuf, usize); dataBuffer = ubuf; dataOffset = 8; receiveSize = usize; } else { throw new AerospikeException("Invalid proto type: " + type + " Expected: " + Command.AS_MSG_TYPE); } if (!ParseGroup(receiveSize)) { break; } } }