// // Copyright (c) ZeroC, Inc. All rights reserved. // namespace IceInternal { using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System.Net; using System; using System.Globalization; sealed class UdpEndpointI : IPEndpointI { public UdpEndpointI(ProtocolInstance instance, string ho, int po, EndPoint sourceAddr, string mcastInterface, int mttl, bool conn, string conId, bool co) : base(instance, ho, po, sourceAddr, conId) { _mcastInterface = mcastInterface; _mcastTtl = mttl; _connect = conn; _compress = co; } public UdpEndpointI(ProtocolInstance instance) : base(instance) { _connect = false; _compress = false; } public UdpEndpointI(ProtocolInstance instance, Ice.InputStream s) : base(instance, s) { if(s.getEncoding().Equals(Ice.Util.Encoding_1_0)) { s.readByte(); s.readByte(); s.readByte(); s.readByte(); } // Not transmitted. //_connect = s.readBool(); _connect = false; _compress = s.readBool(); } private sealed class InfoI : Ice.UDPEndpointInfo { public InfoI(UdpEndpointI e) { _endpoint = e; } override public short type() { return _endpoint.type(); } override public bool datagram() { return _endpoint.datagram(); } override public bool secure() { return _endpoint.secure(); } private UdpEndpointI _endpoint; } // // Return the endpoint information. // public override Ice.EndpointInfo getInfo() { InfoI info = new InfoI(this); fillEndpointInfo(info); return info; } // // Return the timeout for the endpoint in milliseconds. 0 means // non-blocking, -1 means no timeout. // public override int timeout() { return -1; } // // Return a new endpoint with a different timeout value, provided // that timeouts are supported by the endpoint. Otherwise the same // endpoint is returned. // public override EndpointI timeout(int timeout) { return this; } // // Return true if the endpoints support bzip2 compress, or false // otherwise. // public override bool compress() { return _compress; } // // Return a new endpoint with a different compression value, // provided that compression is supported by the // endpoint. Otherwise the same endpoint is returned. // public override EndpointI compress(bool compress) { if(compress == _compress) { return this; } else { return new UdpEndpointI(instance_, host_, port_, sourceAddr_, _mcastInterface, _mcastTtl, _connect, connectionId_, compress); } } // // Return true if the endpoint is datagram-based. // public override bool datagram() { return true; } // // Return a server side transceiver for this endpoint, or null if a // transceiver can only be created by an acceptor. // public override Transceiver transceiver() { return new UdpTransceiver(this, instance_, host_, port_, _mcastInterface, _connect); } // // Return an acceptor for this endpoint, or null if no acceptors // is available. // public override Acceptor acceptor(string adapterName) { return null; } public override void initWithOptions(List args, bool oaEndpoint) { base.initWithOptions(args, oaEndpoint); if(_mcastInterface.Equals("*")) { if(oaEndpoint) { _mcastInterface = ""; } else { throw new Ice.EndpointParseException("`--interface *' not valid for proxy endpoint `" + ToString() + "'"); } } } public UdpEndpointI endpoint(UdpTransceiver transceiver) { int port = transceiver.effectivePort(); if(port == port_) { return this; } else { return new UdpEndpointI(instance_, host_, port, sourceAddr_, _mcastInterface, _mcastTtl, _connect, connectionId_, _compress); } } public override string options() { // // WARNING: Certain features, such as proxy validation in Glacier2, // depend on the format of proxy strings. Changes to toString() and // methods called to generate parts of the reference string could break // these features. Please review for all features that depend on the // format of proxyToString() before changing this and related code. // string s = base.options(); if(_mcastInterface.Length != 0) { bool addQuote = _mcastInterface.IndexOf(':') != -1; s += " --interface "; if(addQuote) { s += "\""; } s += _mcastInterface; if(addQuote) { s += "\""; } } if(_mcastTtl != -1) { s += " --ttl " + _mcastTtl; } if(_connect) { s += " -c"; } if(_compress) { s += " -z"; } return s; } // // Compare endpoints for sorting purposes // public override int CompareTo(EndpointI obj) { if(!(obj is UdpEndpointI)) { return type() < obj.type() ? -1 : 1; } UdpEndpointI p = (UdpEndpointI)obj; if(this == p) { return 0; } if(!_connect && p._connect) { return -1; } else if(!p._connect && _connect) { return 1; } if(!_compress && p._compress) { return -1; } else if(!p._compress && _compress) { return 1; } int rc = string.Compare(_mcastInterface, p._mcastInterface, StringComparison.Ordinal); if(rc != 0) { return rc; } if(_mcastTtl < p._mcastTtl) { return -1; } else if(p._mcastTtl < _mcastTtl) { return 1; } return base.CompareTo(p); } // // Marshal the endpoint // public override void streamWriteImpl(Ice.OutputStream s) { base.streamWriteImpl(s); if(s.getEncoding().Equals(Ice.Util.Encoding_1_0)) { Ice.Util.Protocol_1_0.ice_writeMembers(s); Ice.Util.Encoding_1_0.ice_writeMembers(s); } // Not transmitted. //s.writeBool(_connect); s.writeBool(_compress); } public override void hashInit(ref int h) { base.hashInit(ref h); HashUtil.hashAdd(ref h, _mcastInterface); HashUtil.hashAdd(ref h, _mcastTtl); HashUtil.hashAdd(ref h, _connect); HashUtil.hashAdd(ref h, _compress); } public override void fillEndpointInfo(Ice.IPEndpointInfo info) { base.fillEndpointInfo(info); if(info is Ice.UDPEndpointInfo) { Ice.UDPEndpointInfo udpInfo = (Ice.UDPEndpointInfo)info; udpInfo.timeout = -1; udpInfo.compress = _compress; udpInfo.mcastInterface = _mcastInterface; udpInfo.mcastTtl = _mcastTtl; } } protected override bool checkOption(string option, string argument, string endpoint) { if(base.checkOption(option, argument, endpoint)) { return true; } if(option.Equals("-c")) { if(argument != null) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "unexpected argument `" + argument + "' provided for -c option in " + endpoint; throw e; } _connect = true; } else if(option.Equals("-z")) { if(argument != null) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "unexpected argument `" + argument + "' provided for -z option in " + endpoint; throw e; } _compress = true; } else if(option.Equals("-v") || option.Equals("-e")) { if(argument == null) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "no argument provided for " + option + " option in endpoint " + endpoint; throw e; } try { Ice.EncodingVersion v = Ice.Util.stringToEncodingVersion(argument); if(v.major != 1 || v.minor != 0) { instance_.logger().warning("deprecated udp endpoint option: " + option); } } catch(Ice.VersionParseException ex) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "invalid version `" + argument + "' in endpoint " + endpoint + ":\n" + ex.str; throw e; } } else if(option.Equals("--ttl")) { if(argument == null) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "no argument provided for --ttl option in endpoint " + endpoint; throw e; } try { _mcastTtl = int.Parse(argument, CultureInfo.InvariantCulture); } catch(FormatException ex) { Ice.EndpointParseException e = new Ice.EndpointParseException(ex); e.str = "invalid TTL value `" + argument + "' in endpoint " + endpoint; throw e; } if(_mcastTtl < 0) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "TTL value `" + argument + "' out of range in endpoint " + endpoint; throw e; } } else if(option.Equals("--interface")) { if(argument == null) { Ice.EndpointParseException e = new Ice.EndpointParseException(); e.str = "no argument provided for --interface option in endpoint " + endpoint; throw e; } _mcastInterface = argument; } else { return false; } return true; } protected override Connector createConnector(EndPoint addr, NetworkProxy proxy) { return new UdpConnector(instance_, addr, sourceAddr_, _mcastInterface, _mcastTtl, connectionId_); } protected override IPEndpointI createEndpoint(string host, int port, string connectionId) { return new UdpEndpointI(instance_, host, port, sourceAddr_, _mcastInterface, _mcastTtl, _connect, connectionId, _compress); } private string _mcastInterface = ""; private int _mcastTtl = -1; private bool _connect; private bool _compress; } sealed class UdpEndpointFactory : EndpointFactory { internal UdpEndpointFactory(ProtocolInstance instance) { _instance = instance; } public void initialize() { } public short type() { return _instance.type(); } public string protocol() { return _instance.protocol(); } public EndpointI create(List args, bool oaEndpoint) { IPEndpointI endpt = new UdpEndpointI(_instance); endpt.initWithOptions(args, oaEndpoint); return endpt; } public EndpointI read(Ice.InputStream s) { return new UdpEndpointI(_instance, s); } public void destroy() { _instance = null; } public EndpointFactory clone(ProtocolInstance instance) { return new UdpEndpointFactory(instance); } private ProtocolInstance _instance; } }