/**
*
*/
package net.i2p.sam;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.util.Properties;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
/**
* @author MKVore
*
*/
class SAMv3RawSession extends SAMRawSession implements Session, SAMRawReceiver {
private final String nick;
private final SAMv3Handler handler;
private final SAMv3DatagramServer server;
private final SocketAddress clientAddress;
private final boolean _sendHeader;
public String getNick() { return nick; }
/**
* Build a Raw Datagram Session according to information
* registered with the given nickname
*
* Caller MUST call start().
*
* @param nick nickname of the session
* @throws IOException
* @throws DataFormatException
* @throws I2PSessionException
*/
public SAMv3RawSession(String nick, SAMv3DatagramServer dgServer)
throws IOException, DataFormatException, I2PSessionException {
super(SAMv3Handler.sSessionsHash.get(nick).getDest(),
SAMv3Handler.sSessionsHash.get(nick).getProps(),
null // to be replaced by this
);
this.nick = nick ;
this.recv = this ; // replacement
this.server = dgServer;
SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick);
if (rec == null)
throw new InterruptedIOException() ;
this.handler = rec.getHandler();
Properties props = rec.getProps();
clientAddress = getSocketAddress(props, handler);
_sendHeader = ((handler.verMajor == 3 && handler.verMinor >= 2) || handler.verMajor > 3) &&
Boolean.parseBoolean(props.getProperty("HEADER"));
}
/**
* Build a Raw Session on an existing i2p session
* registered with the given nickname
*
* Caller MUST call start().
*
* @param nick nickname of the session
* @throws IOException
* @throws DataFormatException
* @throws I2PSessionException
* @since 0.9.25
*/
public SAMv3RawSession(String nick, Properties props, SAMv3Handler handler, I2PSession isess,
int listenProtocol, int listenPort, SAMv3DatagramServer dgServer)
throws IOException, DataFormatException, I2PSessionException {
super(isess, props, listenProtocol, listenPort, null); // to be replaced by this
this.nick = nick ;
this.recv = this ; // replacement
this.server = dgServer;
this.handler = handler;
clientAddress = getSocketAddress(props, handler);
_sendHeader = ((handler.verMajor == 3 && handler.verMinor >= 2) || handler.verMajor > 3) &&
Boolean.parseBoolean(props.getProperty("HEADER"));
}
/**
* @return null if PORT not set
* @since 0.9.25 moved from constructor
*/
static SocketAddress getSocketAddress(Properties props, SAMv3Handler handler) {
String portStr = props.getProperty("PORT") ;
if (portStr == null) {
return null;
} else {
int port = Integer.parseInt(portStr);
String host = props.getProperty("HOST");
if ( host==null ) {
host = handler.getClientIP();
}
return new InetSocketAddress(host, port);
}
}
public void receiveRawBytes(byte[] data, int proto, int fromPort, int toPort) throws IOException {
if (this.clientAddress==null) {
this.handler.receiveRawBytes(data, proto, fromPort, toPort);
} else {
ByteBuffer msgBuf;
if (_sendHeader) {
StringBuilder buf = new StringBuilder(64);
buf.append("PROTOCOL=").append(proto)
.append(" FROM_PORT=").append(fromPort)
.append(" TO_PORT=").append(toPort)
.append('\n');
String msg = buf.toString();
msgBuf = ByteBuffer.allocate(msg.length()+data.length);
msgBuf.put(DataHelper.getASCII(msg));
} else {
msgBuf = ByteBuffer.allocate(data.length);
}
msgBuf.put(data);
msgBuf.flip();
this.server.send(this.clientAddress, msgBuf);
}
}
public void stopRawReceiving() {}
}