use of net.i2p.I2PException in project i2p.i2p by i2p.
the class I2PSocketManagerFull method addSubsession.
/**
* For a server, you must call connect() on the returned object.
* Connecting the primary session does NOT connect any subsessions.
* If the primary session is not connected, connecting a subsession will connect the primary session first.
*
* @return a new subsession, non-null
* @param privateKeyStream null for transient, if non-null must have same encryption keys as primary session
* and different signing keys
* @param opts subsession options if any, may be null
* @since 0.9.21
*/
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException {
if (privateKeyStream == null) {
// We don't actually need the same pubkey in the dest, just in the LS.
// The dest one is unused. But this is how we find the LS keys
// to reuse in RequestLeaseSetMessageHandler.
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
try {
SigType type = getSigType(opts);
if (type != SigType.DSA_SHA1) {
// hassle, have to set up the padding and cert, see I2PClientImpl
throw new I2PSessionException("type " + type + " unsupported");
}
PublicKey pub = _session.getMyDestination().getPublicKey();
PrivateKey priv = _session.getDecryptionKey();
SimpleDataStructure[] keys = _context.keyGenerator().generateSigningKeys(type);
pub.writeBytes(keyStream);
// signing pub
keys[0].writeBytes(keyStream);
Certificate.NULL_CERT.writeBytes(keyStream);
priv.writeBytes(keyStream);
// signing priv
keys[1].writeBytes(keyStream);
} catch (GeneralSecurityException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (I2PException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (IOException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (RuntimeException e) {
throw new I2PSessionException("Error creating keys", e);
}
privateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
}
I2PSession rv = _session.addSubsession(privateKeyStream, opts);
boolean added = _subsessions.add(rv);
if (!added) {
// shouldn't happen
_session.removeSubsession(rv);
throw new I2PSessionException("dup");
}
ConnectionOptions defaultOptions = new ConnectionOptions(opts);
int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
rv.addMuxedSessionListener(_connectionManager.getMessageHandler(), protocol, defaultOptions.getLocalPort());
if (_log.shouldLog(Log.WARN))
_log.warn("Added subsession " + rv);
return rv;
}
use of net.i2p.I2PException in project i2p.i2p by i2p.
the class SAMv3StreamSession method connect.
/**
* Connect the SAM STREAM session to the specified Destination
* for a single connection, using the socket stolen from the handler.
*
* @param handler The handler that communicates with the requesting client
* @param dest Base64-encoded Destination to connect to
* @param props Options to be used for connection
*
* @throws DataFormatException if the destination is not valid
* @throws ConnectException if the destination refuses connections
* @throws NoRouteToHostException if the destination can't be reached
* @throws InterruptedIOException if the connection timeouts
* @throws I2PException if there's another I2P-related error
* @throws IOException
*/
public void connect(SAMv3Handler handler, String dest, Properties props) throws I2PException, ConnectException, NoRouteToHostException, DataFormatException, InterruptedIOException, IOException {
boolean verbose = !Boolean.parseBoolean(props.getProperty("SILENT"));
Destination d = SAMUtils.getDest(dest);
I2PSocketOptions opts = socketMgr.buildOptions(props);
if (props.getProperty(I2PSocketOptions.PROP_CONNECT_TIMEOUT) == null)
opts.setConnectTimeout(60 * 1000);
String fromPort = props.getProperty("FROM_PORT");
if (fromPort != null) {
try {
opts.setLocalPort(Integer.parseInt(fromPort));
} catch (NumberFormatException nfe) {
throw new I2PException("Bad port " + fromPort);
}
}
String toPort = props.getProperty("TO_PORT");
if (toPort != null) {
try {
opts.setPort(Integer.parseInt(toPort));
} catch (NumberFormatException nfe) {
throw new I2PException("Bad port " + toPort);
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Connecting new I2PSocket...");
// blocking connection (SAMv3)
I2PSocket i2ps = socketMgr.connect(d, opts);
SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick);
if (rec == null)
throw new InterruptedIOException();
handler.notifyStreamResult(verbose, "OK", null);
handler.stealSocket();
ReadableByteChannel fromClient = handler.getClientSocket();
ReadableByteChannel fromI2P = Channels.newChannel(i2ps.getInputStream());
WritableByteChannel toClient = handler.getClientSocket();
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
SAMBridge bridge = handler.getBridge();
(new I2PAppThread(rec.getThreadGroup(), new Pipe(fromClient, toI2P, bridge), "ConnectV3 SAMPipeClientToI2P")).start();
(new I2PAppThread(rec.getThreadGroup(), new Pipe(fromI2P, toClient, bridge), "ConnectV3 SAMPipeI2PToClient")).start();
}
use of net.i2p.I2PException in project i2p.i2p by i2p.
the class ConnectionManager method receiveConnection.
/**
* Create a new connection based on the SYN packet we received.
*
* @param synPacket SYN packet to process
* @return created Connection with the packet's data already delivered to
* it, or null if the syn's streamId was already taken
*/
public Connection receiveConnection(Packet synPacket) {
ConnectionOptions opts = new ConnectionOptions(_defaultOptions);
opts.setPort(synPacket.getRemotePort());
opts.setLocalPort(synPacket.getLocalPort());
boolean reject = false;
int active = 0;
int total = 0;
// }
if (locked_tooManyStreams()) {
if ((!_defaultOptions.getDisableRejectLogging()) || _log.shouldLog(Log.WARN))
_log.logAlways(Log.WARN, "Refusing connection since we have exceeded our max of " + _defaultOptions.getMaxConns() + " connections");
reject = true;
} else {
// this may not be right if more than one is enabled
String why = shouldRejectConnection(synPacket);
if (why != null) {
if ((!_defaultOptions.getDisableRejectLogging()) || _log.shouldLog(Log.WARN))
_log.logAlways(Log.WARN, "Refusing connection since peer is " + why + (synPacket.getOptionalFrom() == null ? "" : ": " + synPacket.getOptionalFrom().toBase32()));
reject = true;
}
}
_context.statManager().addRateData("stream.receiveActive", active, total);
if (reject) {
Destination from = synPacket.getOptionalFrom();
if (from == null)
return null;
String resp = _defaultOptions.getLimitAction();
if ("drop".equals(resp)) {
// always drop
return null;
}
Hash h = from.calculateHash();
if (_globalBlacklist.contains(h) || (_defaultOptions.isAccessListEnabled() && !_defaultOptions.getAccessList().contains(h)) || (_defaultOptions.isBlacklistEnabled() && _defaultOptions.getBlacklist().contains(h))) {
// always drop these regardless of setting
return null;
}
if ((_minuteThrottler != null && _minuteThrottler.isOverBy(h, DROP_OVER_LIMIT)) || (_hourThrottler != null && _hourThrottler.isOverBy(h, DROP_OVER_LIMIT)) || (_dayThrottler != null && _dayThrottler.isOverBy(h, DROP_OVER_LIMIT))) {
// thus more inbound, but let's not spend several KB on the outbound.
if (_log.shouldLog(Log.INFO))
_log.info("Dropping limit response to " + from.toBase32());
return null;
}
boolean reset = resp == null || resp.equals("reset") || resp.length() <= 0;
boolean http = !reset && "http".equals(resp);
boolean custom = !(reset || http);
String sendResponse;
if (http) {
sendResponse = LIMIT_HTTP_RESPONSE;
} else if (custom) {
sendResponse = resp.replace("\\r", "\r").replace("\\n", "\n");
} else {
sendResponse = null;
}
PacketLocal reply = new PacketLocal(_context, from, synPacket.getSession());
if (sendResponse != null) {
reply.setFlag(Packet.FLAG_SYNCHRONIZE | Packet.FLAG_CLOSE | Packet.FLAG_SIGNATURE_INCLUDED);
reply.setSequenceNum(0);
ByteArray payload = new ByteArray(DataHelper.getUTF8(sendResponse));
reply.setPayload(payload);
} else {
reply.setFlag(Packet.FLAG_RESET | Packet.FLAG_SIGNATURE_INCLUDED);
}
reply.setAckThrough(synPacket.getSequenceNum());
reply.setSendStreamId(synPacket.getReceiveStreamId());
long rcvStreamId = assignRejectId();
reply.setReceiveStreamId(rcvStreamId);
reply.setOptionalFrom();
reply.setLocalPort(synPacket.getLocalPort());
reply.setRemotePort(synPacket.getRemotePort());
if (_log.shouldInfo())
// _log.info("Over limit, sending " + (sendResponse != null ? "configured response" : "reset") + " to " + from.toBase32());
_log.info("Over limit, sending " + reply + " to " + from.toBase32());
// this just sends the packet - no retries or whatnot
_outboundQueue.enqueue(reply);
return null;
}
Connection con = new Connection(_context, this, synPacket.getSession(), _schedulerChooser, _timer, _outboundQueue, _conPacketHandler, opts, true);
_tcbShare.updateOptsFromShare(con);
assignReceiveStreamId(con);
// finally, we know enough that we can log the packet with the conn filled in
if (I2PSocketManagerFull.pcapWriter != null && _context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
synPacket.logTCPDump(con);
try {
// This validates the packet, and sets the con's SendStreamID and RemotePeer
con.getPacketHandler().receivePacket(synPacket, con);
} catch (I2PException ie) {
_connectionByInboundId.remove(Long.valueOf(con.getReceiveStreamId()));
return null;
}
_context.statManager().addRateData("stream.connectionReceived", 1);
return con;
}
use of net.i2p.I2PException in project i2p.i2p by i2p.
the class SAMUtils method genRandomKey.
/**
* Generate a random destination key.
* Caller must close streams. Fails silently.
*
* @param priv Stream used to write the destination and private keys
* @param pub Stream used to write the destination (may be null)
* @param sigType what signature type
* @since 0.9.14
*/
public static void genRandomKey(OutputStream priv, OutputStream pub, SigType sigType) {
// _log.debug("Generating random keys...");
try {
I2PClient c = I2PClientFactory.createClient();
Destination d = c.createDestination(priv, sigType);
priv.flush();
if (pub != null) {
d.writeBytes(pub);
pub.flush();
}
} catch (I2PException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
use of net.i2p.I2PException in project i2p.i2p by i2p.
the class I2PTunnelClient method clientConnectionRun.
protected void clientConnectionRun(Socket s) {
I2PSocket i2ps = null;
try {
I2PSocketAddress addr = pickDestination();
if (addr == null)
throw new UnknownHostException("No valid destination configured");
Destination clientDest = addr.getAddress();
if (clientDest == null)
throw new UnknownHostException("Could not resolve " + addr.getHostName());
int port = addr.getPort();
i2ps = createI2PSocket(clientDest, port);
i2ps.setReadTimeout(readTimeout);
I2PTunnelRunner t = new I2PTunnelRunner(s, i2ps, sockLock, null, null, mySockets, (I2PTunnelRunner.FailCallback) null);
// we are called from an unlimited thread pool, so run inline
// t.start();
t.run();
} catch (IOException ex) {
if (_log.shouldLog(Log.INFO))
_log.info("Error connecting", ex);
} catch (I2PException ex) {
if (_log.shouldLog(Log.INFO))
_log.info("Error connecting", ex);
} finally {
// only because we are running it inline
closeSocket(s);
if (i2ps != null) {
try {
i2ps.close();
} catch (IOException ioe) {
}
synchronized (sockLock) {
mySockets.remove(i2ps);
}
}
}
}
Aggregations