Ejemplo n.º 1
0
        private static void InspectAddressTypes()
        {
            if (_scanned)
            {
                return;
            }

            lock (ScanLock) {
                List <Type> addresses = new List <Type>();
                List <IServiceAddressHandler> addressHandlers = new List <IServiceAddressHandler>();

                Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
                for (int i = 0; i < assemblies.Length; i++)
                {
                    Type[] types = assemblies[i].GetTypes();
                    for (int j = 0; j < types.Length; j++)
                    {
                        Type type = types[j];
                        if (typeof(IServiceAddressHandler).IsAssignableFrom(type) &&
                            !type.IsAbstract &&
                            !type.Equals(typeof(IServiceAddressHandler)))
                        {
                            IServiceAddressHandler handler = (IServiceAddressHandler)Activator.CreateInstance(type);
                            addressHandlers.Add(handler);
                        }
                        else if (typeof(IServiceAddress).IsAssignableFrom(type) &&
                                 !type.IsAbstract &&
                                 !type.Equals(typeof(IServiceAddress)))
                        {
                            addresses.Add(type);
                        }
                    }
                }

                if (addresses.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < addresses.Count; i++)
                {
                    Type type = addresses[i];
                    for (int j = 0; j < addressHandlers.Count; j++)
                    {
                        if (addressHandlers[j].CanHandle(type))
                        {
                            handlers[type] = addressHandlers[j];
                        }
                    }
                }

                _scanned = true;
            }
        }
Ejemplo n.º 2
0
        public void AddNetworkNode(IServiceAddress address)
        {
            lock (stateLock) {
                IServiceAddress[] nodes;
                string            value = GetString(NetworkNodeList, null);
                if (value != null)
                {
                    nodes = ParseAddress(value);
                    int index = Array.BinarySearch(nodes, address);
                    if (index >= 0)
                    {
                        throw new ArgumentException("The address '" + address + "' is already present.");
                    }
                    IServiceAddress[] oldNodes = nodes;
                    nodes = new IServiceAddress[oldNodes.Length + 1];
                    Array.Copy(oldNodes, 0, nodes, 0, oldNodes.Length);
                    nodes[nodes.Length - 1] = address;
                }
                else
                {
                    nodes = new IServiceAddress[] { address };
                }

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < nodes.Length; i++)
                {
                    IServiceAddressHandler handler = ServiceAddresses.GetHandler(nodes[i]);
                    sb.Append(handler.ToString(nodes[i]));

                    if (i < nodes.Length - 1)
                    {
                        sb.Append(", ");
                    }
                }

                SetValue(NetworkNodeList, sb.ToString());
            }
        }
        private static object ReadValue(BinaryReader reader, byte typeCode)
        {
            Type type = GetType(typeCode);

            if (type == typeof(DBNull))
            {
                return(null);
            }
            if (type == typeof(bool))
            {
                return(reader.ReadBoolean());
            }
            if (type == typeof(byte))
            {
                return(reader.ReadByte());
            }
            if (type == typeof(short))
            {
                return(reader.ReadInt16());
            }
            if (type == typeof(int))
            {
                return(reader.ReadInt32());
            }
            if (type == typeof(long))
            {
                return(reader.ReadInt64());
            }
            if (type == typeof(float))
            {
                return(reader.ReadSingle());
            }
            if (type == typeof(double))
            {
                return(reader.ReadDouble());
            }
            if (type == typeof(DateTime))
            {
                return(DateTime.FromBinary(reader.ReadInt64()));
            }

            if (type == typeof(char))
            {
                return(reader.ReadChar());
            }

            if (type == typeof(string))
            {
                int           sz = reader.ReadInt32();
                StringBuilder sb = new StringBuilder(sz);
                for (int i = 0; i < sz; i++)
                {
                    sb.Append(reader.ReadChar());
                }
                return(sb.ToString());
            }

            // Extensions ...

            if (type == typeof(IServiceAddress))
            {
                int  addressTypeCode           = reader.ReadInt32();
                Type addressType               = ServiceAddresses.GetAddressType(addressTypeCode);
                IServiceAddressHandler handler = ServiceAddresses.GetHandler(addressType);
                int    length = reader.ReadInt32();
                byte[] buffer = reader.ReadBytes(length);
                return(handler.FromBytes(buffer));
            }

            if (type == typeof(DataAddress))
            {
                int  dataId      = reader.ReadInt32();
                long blockIdHigh = reader.ReadInt64();
                long blockIdLow  = reader.ReadInt64();
                return(new DataAddress(new BlockId(blockIdHigh, blockIdLow), dataId));
            }

            if (type == typeof(MessageError))
            {
                string source     = reader.ReadString();
                string message    = reader.ReadString();
                string stackTrace = reader.ReadString();
                string errorType  = reader.ReadString();
                return(new MessageError(source, message, stackTrace, errorType));
            }

            if (type == typeof(NodeSet))
            {
                byte nodeSetType = reader.ReadByte();
                // The node_ids list,
                int      sz  = reader.ReadInt32();
                NodeId[] arr = new NodeId[sz];
                for (int n = 0; n < sz; ++n)
                {
                    long nrHigh = reader.ReadInt64();
                    long nrLow  = reader.ReadInt64();
                    arr[n] = new NodeId(nrHigh, nrLow);
                }
                // The binary encoding,
                sz = reader.ReadInt32();
                byte[] buf = new byte[sz];
                // Util.BinaryReader.ReadFully(din, buf, 0, sz);
                reader.Read(buf, 0, sz);
                // Make the node_set object type,
                if (nodeSetType == 1)
                {
                    // Uncompressed single,
                    return(new SingleNodeSet(arr, buf));
                }
                if (nodeSetType == 2)
                {
                    // Compressed group,
                    return(new CompressedNodeSet(arr, buf));
                }

                throw new Exception("Unknown node set type: " + nodeSetType);
            }

            // array
            if (type == typeof(Array))
            {
                byte  arrayTypeCode = reader.ReadByte();
                int   sz            = reader.ReadInt32();
                Type  arrayType     = GetType(arrayTypeCode);
                Array array         = Array.CreateInstance(arrayType, sz);
                for (int i = 0; i < sz; i++)
                {
                    object value = ReadValue(reader);
                    array.SetValue(value, i);
                }

                return(array);
            }

            throw new FormatException();
        }
        private static void WriteValue(object value, BinaryWriter writer)
        {
            Type valueType     = value == null ? typeof(DBNull) : value.GetType();
            byte valueTypeCode = GetCode(valueType);

            writer.Write(valueTypeCode);

            if (value == null)
            {
            }
            else if (valueType == typeof(byte))
            {
                writer.Write((byte)value);
            }
            else if (valueType == typeof(short))
            {
                writer.Write((short)value);
            }
            else if (valueType == typeof(int))
            {
                writer.Write((int)value);
            }
            else if (valueType == typeof(long))
            {
                writer.Write((long)value);
            }
            else if (valueType == typeof(float))
            {
                writer.Write((float)value);
            }
            else if (valueType == typeof(double))
            {
                writer.Write((double)value);
            }
            else if (valueType == typeof(bool))
            {
                writer.Write((bool)value);
            }
            else if (valueType == typeof(DateTime))
            {
                value = ((DateTime)value).ToBinary();
                writer.Write((long)value);
            }
            else if (valueType == typeof(TimeSpan))
            {
                value = ((TimeSpan)value).Ticks;
                writer.Write((long)value);
            }
            else if (valueType == typeof(string))
            {
                string s  = (string)value;
                int    sz = s.Length;
                writer.Write(sz);

                for (int i = 0; i < sz; i++)
                {
                    writer.Write(s[i]);
                }
                // Extensions ...
            }
            else if (typeof(IServiceAddress).IsAssignableFrom(valueType))
            {
                IServiceAddress        address = (IServiceAddress)value;
                IServiceAddressHandler handler = ServiceAddresses.GetHandler(address);
                byte[] buffer = handler.ToBytes(address);
                int    code   = handler.GetCode(address.GetType());
                writer.Write(code);
                writer.Write(buffer.Length);
                writer.Write(buffer);
            }
            else if (valueType == typeof(DataAddress))
            {
                DataAddress dataAddr = (DataAddress)value;
                writer.Write(dataAddr.DataId);
                writer.Write(dataAddr.BlockId.High);
                writer.Write(dataAddr.BlockId.Low);
            }
            else if (valueType == typeof(MessageError))
            {
                MessageError e = (MessageError)value;
                writer.Write(e.Source);
                writer.Write(e.Message);
                writer.Write(e.StackTrace);
            }
            else if (typeof(NodeSet).IsAssignableFrom(valueType))
            {
                if (value is SingleNodeSet)
                {
                    writer.Write((byte)1);
                }
                else if (value is CompressedNodeSet)
                {
                    writer.Write((byte)2);
                }
                else
                {
                    throw new Exception("Unknown NodeSet type: " + value.GetType());
                }
                NodeSet nset = (NodeSet)value;
                // Write the node set,
                NodeId[] nodeIds = nset.NodeIds;
                int      nsz     = nodeIds.Length;
                writer.Write(nsz);
                for (int i = 0; i < nsz; i++)
                {
                    NodeId nodeId = nodeIds[i];
                    writer.Write(nodeId.High);
                    writer.Write(nodeId.Low);
                }
                // Write the binary encoding,
                byte[] buffer = nset.Buffer;
                int    bsz    = buffer.Length;
                writer.Write(bsz);
                writer.Write(buffer, 0, bsz);
            }
            else if (value is Array)
            {
                Array array         = (Array)value;
                Type  arrayType     = array.GetType().GetElementType();
                byte  arrayTypeCode = GetCode(arrayType);

                int sz = array.Length;
                writer.Write(arrayTypeCode);
                writer.Write(sz);

                for (int i = 0; i < sz; i++)
                {
                    object item = array.GetValue(i);
                    WriteValue(item, writer);
                }
            }
        }
Ejemplo n.º 5
0
            public void Process(object state)
            {
                Socket socket = (Socket)state;

                Stream socket_in  = new NetworkStream(socket, FileAccess.Read);
                Stream socket_out = new NetworkStream(socket, FileAccess.Write);

                try {
                    // 30 minute timeout on proxy connections,
                    socket.SendTimeout = 30 * 60 * 1000;

                    // Wrap the input stream in a data and buffered input stream,
                    BufferedStream bin = new BufferedStream(socket_in, 1024);
                    BinaryReader   din = new BinaryReader(bin);

                    // Wrap the output stream in a data and buffered output stream,
                    BufferedStream bout = new BufferedStream(socket_out, 1024);
                    BinaryWriter   dout = new BinaryWriter(bout);

                    // Perform the handshake,
                    DateTime systemtime = DateTime.Now;
                    dout.Write(systemtime.ToUniversalTime().ToBinary());
                    dout.Flush();
                    long back = din.ReadInt64();
                    if (systemtime.ToUniversalTime().ToBinary() != back)
                    {
                        throw new IOException("Bad protocol request");
                    }
                    dout.Write("CloudB Proxy Service");
                    dout.Flush();
                    string net_password = din.ReadString();

                    // The connector to proxy commands via,
                    TcpServiceConnector connector = new TcpServiceConnector(net_password);

                    // The rest of the communication will be command requests;
                    while (true)
                    {
                        // Read the command,
                        char command = din.ReadChar();
                        if (command == '0')
                        {
                            // Close connection if we receive a '0' command char
                            dout.Close();
                            din.Close();
                            return;
                        }

                        int  addressCode = din.ReadInt32();
                        Type addressType = ServiceAddresses.GetAddressType(addressCode);
                        if (addressType == null || addressType != typeof(TcpServiceAddress))
                        {
                            throw new ApplicationException("Invalid address type.");
                        }

                        int    addressLength = din.ReadInt32();
                        byte[] addressBytes  = new byte[addressLength];
                        din.Read(addressBytes, 0, addressLength);

                        IServiceAddressHandler handler = ServiceAddresses.GetHandler(addressType);
                        TcpServiceAddress      address = (TcpServiceAddress)handler.FromBytes(addressBytes);
                        IEnumerable <Message>  request = service.MessageSerializer.Deserialize(din.BaseStream);

                        Message response;

                        // Proxy the command over the network,
                        if (command == 'a')
                        {
                            response = connector.Connect(address, ServiceType.Admin).Process(request);
                        }
                        else if (command == 'b')
                        {
                            response = connector.Connect(address, ServiceType.Block).Process(request);
                        }
                        else if (command == 'm')
                        {
                            response = connector.Connect(address, ServiceType.Manager).Process(request);
                        }
                        else if (command == 'r')
                        {
                            response = connector.Connect(address, ServiceType.Root).Process(request);
                        }
                        else
                        {
                            throw new IOException("Unknown command to proxy: " + command);
                        }

                        // Return the result,
                        service.MessageSerializer.Serialize(response, dout.BaseStream);
                        dout.Flush();
                    }
                } catch (SocketException e) {
                    if (e.ErrorCode == (int)SocketError.ConnectionReset)
                    {
                        // Ignore connection reset messages,
                    }
                } catch (IOException e) {
                    if (e is EndOfStreamException)
                    {
                        // Ignore this one oo,
                    }
                    else
                    {
                        service.Logger.Error("IO Error during connection input", e);
                    }
                } finally {
                    // Make sure the socket is closed before we return from the thread,
                    try {
                        socket.Close();
                    } catch (IOException e) {
                        service.Logger.Error("IO Error on connection close", e);
                    }
                }
            }