use of net.i2p.util.I2PSSLSocketFactory in project i2p.i2p by i2p.
the class SAMStreamSend method connect.
private Socket connect(boolean isSSL) throws IOException {
int port = Integer.parseInt(_samPort);
if (!isSSL)
return new Socket(_samHost, port);
synchronized (SAMStreamSink.class) {
if (_sslSocketFactory == null) {
try {
_sslSocketFactory = new I2PSSLSocketFactory(_context, true, "certificates/sam");
} catch (GeneralSecurityException gse) {
throw new IOException("SSL error", gse);
}
}
}
SSLSocket sock = (SSLSocket) _sslSocketFactory.createSocket(_samHost, port);
I2PSSLSocketFactory.verifyHostname(_context, sock, _samHost);
return sock;
}
use of net.i2p.util.I2PSSLSocketFactory in project i2p.i2p by i2p.
the class I2PSessionImpl method connect.
/**
* Connect to the router and establish a session. This call blocks until
* a session is granted.
*
* Should be threadsafe, other threads will block until complete.
* Disconnect / destroy from another thread may be called simultaneously and
* will (should?) interrupt the connect.
*
* Connecting a primary session will not automatically connect subsessions.
* Connecting a subsession will automatically connect the primary session
* if not previously connected.
*
* @throws I2PSessionException if there is a configuration error or the router is
* not reachable
*/
public void connect() throws I2PSessionException {
synchronized (_stateLock) {
boolean wasOpening = false;
boolean loop = true;
while (loop) {
switch(_state) {
case INIT:
loop = false;
break;
case CLOSED:
if (wasOpening)
throw new I2PSessionException("connect by other thread failed");
loop = false;
break;
case OPENING:
case GOTDATE:
wasOpening = true;
try {
_stateLock.wait(10 * 1000);
} catch (InterruptedException ie) {
throw new I2PSessionException("Interrupted", ie);
}
break;
case CLOSING:
throw new I2PSessionException("close in progress");
case OPEN:
return;
}
}
changeState(State.OPENING);
}
_availabilityNotifier.stopNotifying();
if ((_options != null) && (I2PClient.PROP_RELIABILITY_GUARANTEED.equals(_options.getProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT)))) {
if (_log.shouldLog(Log.ERROR))
_log.error("I2CP guaranteed delivery mode has been removed, using best effort.");
}
boolean success = false;
long startConnect = _context.clock().now();
try {
// protect w/ closeSocket()
synchronized (_stateLock) {
// If we are in the router JVM, connect using the internal queue
if (_context.isRouterContext()) {
// _socket and _writer remain null
InternalClientManager mgr = _context.internalClientManager();
if (mgr == null)
throw new I2PSessionException("Router is not ready for connections");
// the following may throw an I2PSessionException
_queue = mgr.connect();
_reader = new QueuedI2CPMessageReader(_queue, this);
} else {
if (SystemVersion.isAndroid() && _options.getProperty(PROP_DOMAIN_SOCKET) != null) {
try {
Class<?> clazz = Class.forName("net.i2p.client.DomainSocketFactory");
Constructor<?> ctor = clazz.getDeclaredConstructor(I2PAppContext.class);
Object fact = ctor.newInstance(_context);
Method createSocket = clazz.getDeclaredMethod("createSocket", String.class);
try {
_socket = (Socket) createSocket.invoke(fact, _options.getProperty(PROP_DOMAIN_SOCKET));
} catch (InvocationTargetException e) {
throw new I2PSessionException("Cannot create domain socket", e);
}
} catch (ClassNotFoundException e) {
throw new I2PSessionException("Cannot load DomainSocketFactory", e);
} catch (NoSuchMethodException e) {
throw new I2PSessionException("Cannot load DomainSocketFactory", e);
} catch (InstantiationException e) {
throw new I2PSessionException("Cannot load DomainSocketFactory", e);
} catch (IllegalAccessException e) {
throw new I2PSessionException("Cannot load DomainSocketFactory", e);
} catch (InvocationTargetException e) {
throw new I2PSessionException("Cannot load DomainSocketFactory", e);
}
} else if (Boolean.parseBoolean(_options.getProperty(PROP_ENABLE_SSL))) {
try {
I2PSSLSocketFactory fact = new I2PSSLSocketFactory(_context, false, "certificates/i2cp");
_socket = fact.createSocket(_hostname, _portNum);
_socket.setKeepAlive(true);
} catch (GeneralSecurityException gse) {
IOException ioe = new IOException("SSL Fail");
ioe.initCause(gse);
throw ioe;
}
} else {
_socket = new Socket(_hostname, _portNum);
_socket.setKeepAlive(true);
}
// _socket.setSoTimeout(1000000); // Uhmmm we could really-really use a real timeout, and handle it.
OutputStream out = _socket.getOutputStream();
out.write(I2PClient.PROTOCOL_BYTE);
out.flush();
_writer = new ClientWriterRunner(out, this);
_writer.startWriting();
InputStream in = new BufferedInputStream(_socket.getInputStream(), BUF_SIZE);
_reader = new I2CPMessageReader(in, this);
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "before startReading");
_reader.startReading();
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Before getDate");
Properties auth = null;
if ((!_context.isRouterContext()) && _options.containsKey(PROP_USER) && _options.containsKey(PROP_PW)) {
// Only supported by routers 0.9.11 or higher, but we don't know the version yet.
// Auth will also be sent in the SessionConfig.
auth = new OrderedProperties();
auth.setProperty(PROP_USER, _options.getProperty(PROP_USER));
auth.setProperty(PROP_PW, _options.getProperty(PROP_PW));
}
sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION, auth));
waitForDate();
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Before producer.connect()");
_producer.connect(this);
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "After producer.connect()");
// wait until we have created a lease set
int waitcount = 0;
while (_leaseSet == null) {
if (waitcount++ > 5 * 60) {
throw new IOException("No tunnels built after waiting 5 minutes. Your network connection may be down, or there is severe network congestion.");
}
synchronized (_leaseSetWait) {
// InterruptedException caught below
_leaseSetWait.wait(1000);
}
// if we got a disconnect message while waiting
if (isClosed())
throw new IOException("Disconnected from router while waiting for tunnels");
}
if (_log.shouldLog(Log.INFO)) {
long connected = _context.clock().now();
_log.info(getPrefix() + "Lease set created with inbound tunnels after " + (connected - startConnect) + "ms - ready to participate in the network!");
}
Thread notifier = new I2PAppThread(_availabilityNotifier, "ClientNotifier " + getPrefix(), true);
notifier.start();
startIdleMonitor();
startVerifyUsage();
success = true;
// now send CreateSessionMessages for all subsessions, one at a time, must wait for each response
synchronized (_subsessionLock) {
for (SubSession ss : _subsessions) {
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix() + "Connecting subsession " + ss);
_producer.connect(ss);
}
}
} catch (InterruptedException ie) {
throw new I2PSessionException("Interrupted", ie);
} catch (UnknownHostException uhe) {
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
} catch (IOException ioe) {
// Generate the best error message as this will be logged
String msg;
if (_context.isRouterContext())
msg = "Failed to build tunnels";
else if (SystemVersion.isAndroid() && _options.getProperty(PROP_DOMAIN_SOCKET) != null)
msg = "Failed to bind to the router on " + _options.getProperty(PROP_DOMAIN_SOCKET) + " and build tunnels";
else
msg = "Cannot connect to the router on " + _hostname + ':' + _portNum + " and build tunnels";
throw new I2PSessionException(getPrefix() + msg, ioe);
} finally {
if (success) {
changeState(State.OPEN);
} else {
_availabilityNotifier.stopNotifying();
synchronized (_stateLock) {
changeState(State.CLOSING);
try {
_producer.disconnect(this);
} catch (I2PSessionException ipe) {
}
closeSocket();
}
}
}
}
use of net.i2p.util.I2PSSLSocketFactory in project i2p.i2p by i2p.
the class I2PSimpleSession method connect.
/**
* Connect to the router and establish a session. This call blocks until
* a session is granted.
*
* NOT threadsafe, do not call from multiple threads.
*
* @throws I2PSessionException if there is a configuration error or the router is
* not reachable
*/
@Override
public void connect() throws I2PSessionException {
changeState(State.OPENING);
boolean success = false;
try {
// protect w/ closeSocket()
synchronized (_stateLock) {
// If we are in the router JVM, connect using the interal queue
if (_context.isRouterContext()) {
// _socket and _writer remain null
InternalClientManager mgr = _context.internalClientManager();
if (mgr == null)
throw new I2PSessionException("Router is not ready for connections");
// the following may throw an I2PSessionException
_queue = mgr.connect();
_reader = new QueuedI2CPMessageReader(_queue, this);
_reader.startReading();
} else {
if (Boolean.parseBoolean(getOptions().getProperty(PROP_ENABLE_SSL))) {
try {
I2PSSLSocketFactory fact = new I2PSSLSocketFactory(_context, false, "certificates/i2cp");
_socket = fact.createSocket(_hostname, _portNum);
} catch (GeneralSecurityException gse) {
IOException ioe = new IOException("SSL Fail");
ioe.initCause(gse);
throw ioe;
}
} else {
_socket = new Socket(_hostname, _portNum);
}
_socket.setKeepAlive(true);
OutputStream out = _socket.getOutputStream();
out.write(I2PClient.PROTOCOL_BYTE);
out.flush();
_writer = new ClientWriterRunner(out, this);
_writer.startWriting();
InputStream in = new BufferedInputStream(_socket.getInputStream(), BUF_SIZE);
_reader = new I2CPMessageReader(in, this);
_reader.startReading();
}
}
// must be out of synch block for writer to get unblocked
if (!_context.isRouterContext()) {
Properties opts = getOptions();
// support the AuthMessage
if ((!opts.containsKey(PROP_USER)) && (!opts.containsKey(PROP_PW))) {
// auto-add auth if not set in the options
String configUser = _context.getProperty(PROP_USER);
String configPW = _context.getProperty(PROP_PW);
if (configUser != null && configPW != null) {
opts.setProperty(PROP_USER, configUser);
opts.setProperty(PROP_PW, configPW);
}
}
if (opts.containsKey(PROP_USER) && opts.containsKey(PROP_PW)) {
Properties auth = new OrderedProperties();
auth.setProperty(PROP_USER, opts.getProperty(PROP_USER));
auth.setProperty(PROP_PW, opts.getProperty(PROP_PW));
sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION, auth));
} else {
// we must now send a GetDate even in SimpleSession, or we won't know
// what version we are talking with and cannot use HostLookup
sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION));
}
waitForDate();
}
// we do not receive payload messages, so we do not need an AvailabilityNotifier
// ... or an Idle timer, or a VerifyUsage
success = true;
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix() + " simple session connected");
} catch (InterruptedException ie) {
throw new I2PSessionException("Interrupted", ie);
} catch (UnknownHostException uhe) {
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
} catch (IOException ioe) {
// Generate the best error message as this will be logged
String msg;
if (_context.isRouterContext())
msg = "Failed internal router binding";
else if (SystemVersion.isAndroid() && Boolean.parseBoolean(getOptions().getProperty(PROP_DOMAIN_SOCKET)))
msg = "Failed to bind to the router";
else
msg = "Cannot connect to the router on " + _hostname + ':' + _portNum;
throw new I2PSessionException(getPrefix() + msg, ioe);
} finally {
changeState(success ? State.OPEN : State.CLOSED);
}
}
use of net.i2p.util.I2PSSLSocketFactory in project i2p.i2p by i2p.
the class I2PTunnelServer method getSocket.
/**
* Get a regular or SSL socket depending on config.
* The SSL config applies to all hosts/ports.
*
* @param from may be used to construct local address since 0.9.13
* @since 0.9.9
*/
protected Socket getSocket(Hash from, InetAddress remoteHost, int remotePort) throws IOException {
String opt = getTunnel().getClientOptions().getProperty(PROP_USE_SSL);
if (Boolean.parseBoolean(opt)) {
synchronized (sslLock) {
if (_sslFactory == null) {
try {
_sslFactory = new I2PSSLSocketFactory(getTunnel().getContext(), true, "certificates/i2ptunnel");
} catch (GeneralSecurityException gse) {
IOException ioe = new IOException("SSL Fail");
ioe.initCause(gse);
throw ioe;
}
}
}
return _sslFactory.createSocket(remoteHost, remotePort);
} else {
// as suggested in https://lists.torproject.org/pipermail/tor-dev/2014-March/006576.html
boolean unique = Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_UNIQUE_LOCAL));
if (unique && remoteHost.isLoopbackAddress()) {
byte[] addr;
if (remoteHost instanceof Inet4Address) {
addr = new byte[4];
addr[0] = 127;
System.arraycopy(from.getData(), 0, addr, 1, 3);
} else {
addr = new byte[16];
addr[0] = (byte) 0xfd;
System.arraycopy(from.getData(), 0, addr, 1, 15);
}
InetAddress local = InetAddress.getByAddress(addr);
// Not clear if supported in Java 6 or not.
return new Socket(remoteHost, remotePort, local, 0);
} else {
return new Socket(remoteHost, remotePort);
}
}
}
use of net.i2p.util.I2PSSLSocketFactory in project i2p.i2p by i2p.
the class SAMStreamSink method connect.
private Socket connect(boolean isSSL) throws IOException {
int port = Integer.parseInt(_samPort);
if (!isSSL)
return new Socket(_samHost, port);
synchronized (SAMStreamSink.class) {
if (_sslSocketFactory == null) {
try {
_sslSocketFactory = new I2PSSLSocketFactory(_context, true, "certificates/sam");
} catch (GeneralSecurityException gse) {
throw new IOException("SSL error", gse);
}
}
}
SSLSocket sock = (SSLSocket) _sslSocketFactory.createSocket(_samHost, port);
I2PSSLSocketFactory.verifyHostname(_context, sock, _samHost);
return sock;
}
Aggregations