TcpEndpointI.java
// Copyright (c) ZeroC, Inc.
package com.zeroc.Ice;
import com.zeroc.Ice.SSL.SSLEngineFactory;
import java.net.InetSocketAddress;
final class TcpEndpointI extends IPEndpointI {
private static final int defaultTimeout = 60_000; // 60,000 milliseconds (1 minute)
public TcpEndpointI(
ProtocolInstance instance,
String ho,
int po,
InetSocketAddress sourceAddr,
int ti,
String conId,
boolean co) {
super(instance, ho, po, sourceAddr, conId);
_timeout = ti;
_compress = co;
}
public TcpEndpointI(ProtocolInstance instance) {
super(instance);
// The timeout is not used in Ice 3.8 or greater.
_timeout = defaultTimeout;
_compress = false;
}
public TcpEndpointI(ProtocolInstance instance, InputStream s) {
super(instance, s);
_timeout = s.readInt();
_compress = s.readBool();
}
//
// Return the endpoint information.
//
@Override
public EndpointInfo getInfo() {
return new TCPEndpointInfo(
_compress,
_host,
_port,
_sourceAddr == null ? "" : _sourceAddr.getAddress().getHostAddress(),
type(),
secure());
}
//
// Return the timeout for the endpoint in milliseconds. 0 means
// non-blocking, -1 means no timeout.
//
@Override
public int timeout() {
return _timeout;
}
//
// Return a new endpoint with a different timeout value, provided
// that timeouts are supported by the endpoint. Otherwise the same
// endpoint is returned.
//
@Override
public EndpointI timeout(int timeout) {
if (timeout == _timeout) {
return this;
} else {
return new TcpEndpointI(
_instance, _host, _port, _sourceAddr, timeout, _connectionId, _compress);
}
}
//
// Return true if the endpoints support bzip2 compress, or false
// otherwise.
//
@Override
public boolean 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.
//
@Override
public EndpointI compress(boolean compress) {
if (compress == _compress) {
return this;
} else {
return new TcpEndpointI(
_instance, _host, _port, _sourceAddr, _timeout, _connectionId, compress);
}
}
//
// Return true if the endpoint is datagram-based.
//
@Override
public boolean datagram() {
return false;
}
//
// Return a server side transceiver for this endpoint, or null if a
// transceiver can only be created by an acceptor.
//
@Override
public Transceiver transceiver() {
return null;
}
//
// Return an acceptor for this endpoint, or null if no acceptors
// is available.
//
@Override
public Acceptor acceptor(String adapterName, SSLEngineFactory factory) {
assert (factory == null);
return new TcpAcceptor(this, _instance, _host, _port);
}
public TcpEndpointI endpoint(TcpAcceptor acceptor) {
int port = acceptor.effectivePort();
if (port == _port) {
return this;
} else {
return new TcpEndpointI(
_instance, _host, port, _sourceAddr, _timeout, _connectionId, _compress);
}
}
@Override
public 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 = super.options();
if (_timeout != defaultTimeout) {
if (_timeout == -1) {
s += " -t infinite";
} else {
s += " -t " + _timeout;
}
}
if (_compress) {
s += " -z";
}
return s;
}
//
// Compare endpoints for sorting purposes
//
@Override
public int compareTo(EndpointI obj) {
if (!(obj instanceof TcpEndpointI)) {
return type() < obj.type() ? -1 : 1;
}
TcpEndpointI p = (TcpEndpointI) obj;
if (this == p) {
return 0;
}
if (_timeout < p._timeout) {
return -1;
} else if (p._timeout < _timeout) {
return 1;
}
if (!_compress && p._compress) {
return -1;
} else if (!p._compress && _compress) {
return 1;
}
return super.compareTo(obj);
}
@Override
public void streamWriteImpl(OutputStream s) {
super.streamWriteImpl(s);
s.writeInt(_timeout);
s.writeBool(_compress);
}
@Override
public int hashCode() {
int h = super.hashCode();
h = HashUtil.hashAdd(h, _timeout);
h = HashUtil.hashAdd(h, _compress);
return h;
}
@Override
public EndpointI toPublishedEndpoint(String publishedHost) {
// A server endpoint can't have a source address or connection ID.
assert (_sourceAddr == null && _connectionId.isEmpty());
if (publishedHost.isEmpty()) {
return this;
} else {
return new TcpEndpointI(_instance, publishedHost, _port, null, _timeout, "", _compress);
}
}
@Override
protected boolean checkOption(String option, String argument, String endpoint) {
if (super.checkOption(option, argument, endpoint)) {
return true;
}
switch (option.charAt(1)) {
case 't': {
if (argument == null) {
throw new ParseException(
"no argument provided for -t option in endpoint '"
+ endpoint
+ "'");
}
if ("infinite".equals(argument)) {
_timeout = -1;
} else {
try {
_timeout = Integer.parseInt(argument);
if (_timeout < 1) {
throw new ParseException(
"invalid timeout value '"
+ argument
+ "' in endpoint '"
+ endpoint
+ "'");
}
} catch (NumberFormatException ex) {
throw new ParseException(
"invalid timeout value '"
+ argument
+ "' in endpoint '"
+ endpoint
+ "'",
ex);
}
}
return true;
}
case 'z': {
if (argument != null) {
throw new ParseException(
"unexpected argument '"
+ argument
+ "' provided for -z option in '"
+ endpoint
+ "'");
}
_compress = true;
return true;
}
default: {
return false;
}
}
}
@Override
protected Connector createConnector(InetSocketAddress addr, NetworkProxy proxy) {
return new TcpConnector(_instance, addr, proxy, _sourceAddr, _timeout, _connectionId);
}
@Override
protected IPEndpointI createEndpoint(String host, int port, String connectionId) {
return new TcpEndpointI(
_instance, host, port, _sourceAddr, _timeout, connectionId, _compress);
}
private int _timeout;
private boolean _compress;
}