Code cleanup.
Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
04060ce567
commit
d25fa7d20c
|
@ -39,10 +39,8 @@ import org.eclipse.jetty.util.TypeUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* ConnectionFactory for the PROXY Protocol.
|
* <p>ConnectionFactory for the PROXY Protocol.</p>
|
||||||
* <p>This factory can be placed in front of any other connection factory
|
* <p>This factory can be placed in front of any other connection factory
|
||||||
* to process the proxy v1 or v2 line before the normal protocol handling</p>
|
* to process the proxy v1 or v2 line before the normal protocol handling</p>
|
||||||
*
|
*
|
||||||
|
@ -50,26 +48,26 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
*/
|
*/
|
||||||
public class ProxyConnectionFactory extends AbstractConnectionFactory
|
public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
{
|
{
|
||||||
|
private static final Logger LOG = Log.getLogger(ProxyConnectionFactory.class);
|
||||||
public static final String TLS_VERSION = "TLS_VERSION";
|
public static final String TLS_VERSION = "TLS_VERSION";
|
||||||
|
|
||||||
private static final Logger LOG = Log.getLogger(ProxyConnectionFactory.class);
|
|
||||||
private final String _next;
|
private final String _next;
|
||||||
private int _maxProxyHeader=1024;
|
private int _maxProxyHeader = 1024;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
/** Proxy Connection Factory that uses the next ConnectionFactory
|
* Proxy Connection Factory that uses the next ConnectionFactory
|
||||||
* on the connector as the next protocol
|
* on the connector as the next protocol
|
||||||
*/
|
*/
|
||||||
public ProxyConnectionFactory()
|
public ProxyConnectionFactory()
|
||||||
{
|
{
|
||||||
super("proxy");
|
super("proxy");
|
||||||
_next=null;
|
_next = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyConnectionFactory(String nextProtocol)
|
public ProxyConnectionFactory(String nextProtocol)
|
||||||
{
|
{
|
||||||
super("proxy");
|
super("proxy");
|
||||||
_next=nextProtocol;
|
_next = nextProtocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxProxyHeader()
|
public int getMaxProxyHeader()
|
||||||
|
@ -85,21 +83,21 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
@Override
|
@Override
|
||||||
public Connection newConnection(Connector connector, EndPoint endp)
|
public Connection newConnection(Connector connector, EndPoint endp)
|
||||||
{
|
{
|
||||||
String next=_next;
|
String next = _next;
|
||||||
if (next==null)
|
if (next == null)
|
||||||
{
|
{
|
||||||
for (Iterator<String> i = connector.getProtocols().iterator();i.hasNext();)
|
for (Iterator<String> i = connector.getProtocols().iterator(); i.hasNext(); )
|
||||||
{
|
{
|
||||||
String p=i.next();
|
String p = i.next();
|
||||||
if (getProtocol().equalsIgnoreCase(p))
|
if (getProtocol().equalsIgnoreCase(p))
|
||||||
{
|
{
|
||||||
next=i.next();
|
next = i.next();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProxyProtocolV1orV2Connection(endp,connector,next);
|
return new ProxyProtocolV1orV2Connection(endp, connector, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProxyProtocolV1orV2Connection extends AbstractConnection
|
public class ProxyProtocolV1orV2Connection extends AbstractConnection
|
||||||
|
@ -110,9 +108,9 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
|
|
||||||
protected ProxyProtocolV1orV2Connection(EndPoint endp, Connector connector, String next)
|
protected ProxyProtocolV1orV2Connection(EndPoint endp, Connector connector, String next)
|
||||||
{
|
{
|
||||||
super(endp,connector.getExecutor());
|
super(endp, connector.getExecutor());
|
||||||
_connector=connector;
|
_connector = connector;
|
||||||
_next=next;
|
_next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,16 +125,16 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while(BufferUtil.space(_buffer)>0)
|
while (BufferUtil.space(_buffer) > 0)
|
||||||
{
|
{
|
||||||
// Read data
|
// Read data
|
||||||
int fill=getEndPoint().fill(_buffer);
|
int fill = getEndPoint().fill(_buffer);
|
||||||
if (fill<0)
|
if (fill < 0)
|
||||||
{
|
{
|
||||||
getEndPoint().shutdownOutput();
|
getEndPoint().shutdownOutput();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fill==0)
|
if (fill == 0)
|
||||||
{
|
{
|
||||||
fillInterested();
|
fillInterested();
|
||||||
return;
|
return;
|
||||||
|
@ -144,28 +142,28 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is it a V1?
|
// Is it a V1?
|
||||||
switch(_buffer.get(0))
|
switch (_buffer.get(0))
|
||||||
{
|
{
|
||||||
case 'P':
|
case 'P':
|
||||||
{
|
{
|
||||||
ProxyProtocolV1Connection v1 = new ProxyProtocolV1Connection(getEndPoint(),_connector,_next,_buffer);
|
ProxyProtocolV1Connection v1 = new ProxyProtocolV1Connection(getEndPoint(), _connector, _next, _buffer);
|
||||||
getEndPoint().upgrade(v1);
|
getEndPoint().upgrade(v1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
{
|
{
|
||||||
ProxyProtocolV2Connection v2 = new ProxyProtocolV2Connection(getEndPoint(),_connector,_next,_buffer);
|
ProxyProtocolV2Connection v2 = new ProxyProtocolV2Connection(getEndPoint(), _connector, _next, _buffer);
|
||||||
getEndPoint().upgrade(v2);
|
getEndPoint().upgrade(v2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LOG.warn("Not PROXY protocol for {}",getEndPoint());
|
LOG.warn("Not PROXY protocol for {}", getEndPoint());
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.warn("PROXY error for "+getEndPoint(),x);
|
LOG.warn("PROXY error for " + getEndPoint(), x);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,20 +175,20 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
// 98765432109876543210987654321
|
// 98765432109876543210987654321
|
||||||
// PROXY P R.R.R.R L.L.L.L R Lrn
|
// PROXY P R.R.R.R L.L.L.L R Lrn
|
||||||
|
|
||||||
private final int[] __size = {29,23,21,13,5,3,1};
|
private final int[] __size = {29, 23, 21, 13, 5, 3, 1};
|
||||||
private final Connector _connector;
|
private final Connector _connector;
|
||||||
private final String _next;
|
private final String _next;
|
||||||
private final StringBuilder _builder=new StringBuilder();
|
private final StringBuilder _builder = new StringBuilder();
|
||||||
private final String[] _field=new String[6];
|
private final String[] _field = new String[6];
|
||||||
private int _fields;
|
private int _fields;
|
||||||
private int _length;
|
private int _length;
|
||||||
|
|
||||||
protected ProxyProtocolV1Connection(EndPoint endp, Connector connector, String next,ByteBuffer buffer)
|
protected ProxyProtocolV1Connection(EndPoint endp, Connector connector, String next, ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
super(endp,connector.getExecutor());
|
super(endp, connector.getExecutor());
|
||||||
_connector=connector;
|
_connector = connector;
|
||||||
_next=next;
|
_next = next;
|
||||||
_length=buffer.remaining();
|
_length = buffer.remaining();
|
||||||
parse(buffer);
|
parse(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,23 +199,22 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
fillInterested();
|
fillInterested();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean parse(ByteBuffer buffer)
|
private boolean parse(ByteBuffer buffer)
|
||||||
{
|
{
|
||||||
// parse fields
|
// parse fields
|
||||||
while (buffer.hasRemaining())
|
while (buffer.hasRemaining())
|
||||||
{
|
{
|
||||||
byte b = buffer.get();
|
byte b = buffer.get();
|
||||||
if (_fields<6)
|
if (_fields < 6)
|
||||||
{
|
{
|
||||||
if (b==' ' || b=='\r' && _fields==5)
|
if (b == ' ' || b == '\r' && _fields == 5)
|
||||||
{
|
{
|
||||||
_field[_fields++]=_builder.toString();
|
_field[_fields++] = _builder.toString();
|
||||||
_builder.setLength(0);
|
_builder.setLength(0);
|
||||||
}
|
}
|
||||||
else if (b<' ')
|
else if (b < ' ')
|
||||||
{
|
{
|
||||||
LOG.warn("Bad character {} for {}",b&0xFF,getEndPoint());
|
LOG.warn("Bad character {} for {}", b & 0xFF, getEndPoint());
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -228,18 +225,17 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (b=='\n')
|
if (b == '\n')
|
||||||
{
|
{
|
||||||
_fields=7;
|
_fields = 7;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.warn("Bad CRLF for {}",getEndPoint());
|
LOG.warn("Bad CRLF for {}", getEndPoint());
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,35 +244,35 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ByteBuffer buffer=null;
|
ByteBuffer buffer = null;
|
||||||
while(_fields<7)
|
while (_fields < 7)
|
||||||
{
|
{
|
||||||
// Create a buffer that will not read too much data
|
// Create a buffer that will not read too much data
|
||||||
// since once read it is impossible to push back for the
|
// since once read it is impossible to push back for the
|
||||||
// real connection to read it.
|
// real connection to read it.
|
||||||
int size=Math.max(1,__size[_fields]-_builder.length());
|
int size = Math.max(1, __size[_fields] - _builder.length());
|
||||||
if (buffer==null || buffer.capacity()!=size)
|
if (buffer == null || buffer.capacity() != size)
|
||||||
buffer=BufferUtil.allocate(size);
|
buffer = BufferUtil.allocate(size);
|
||||||
else
|
else
|
||||||
BufferUtil.clear(buffer);
|
BufferUtil.clear(buffer);
|
||||||
|
|
||||||
// Read data
|
// Read data
|
||||||
int fill=getEndPoint().fill(buffer);
|
int fill = getEndPoint().fill(buffer);
|
||||||
if (fill<0)
|
if (fill < 0)
|
||||||
{
|
{
|
||||||
getEndPoint().shutdownOutput();
|
getEndPoint().shutdownOutput();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fill==0)
|
if (fill == 0)
|
||||||
{
|
{
|
||||||
fillInterested();
|
fillInterested();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_length+=fill;
|
_length += fill;
|
||||||
if (_length>=108)
|
if (_length >= 108)
|
||||||
{
|
{
|
||||||
LOG.warn("PROXY line too long {} for {}",_length,getEndPoint());
|
LOG.warn("PROXY line too long {} for {}", _length, getEndPoint());
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -288,43 +284,50 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
// Check proxy
|
// Check proxy
|
||||||
if (!"PROXY".equals(_field[0]))
|
if (!"PROXY".equals(_field[0]))
|
||||||
{
|
{
|
||||||
LOG.warn("Not PROXY protocol for {}",getEndPoint());
|
LOG.warn("Not PROXY protocol for {}", getEndPoint());
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract Addresses
|
// Extract Addresses
|
||||||
InetSocketAddress remote=new InetSocketAddress(_field[2],Integer.parseInt(_field[4]));
|
InetSocketAddress remote = new InetSocketAddress(_field[2], Integer.parseInt(_field[4]));
|
||||||
InetSocketAddress local =new InetSocketAddress(_field[3],Integer.parseInt(_field[5]));
|
InetSocketAddress local = new InetSocketAddress(_field[3], Integer.parseInt(_field[5]));
|
||||||
|
|
||||||
// Create the next protocol
|
// Create the next protocol
|
||||||
ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next);
|
ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next);
|
||||||
if (connectionFactory == null)
|
if (connectionFactory == null)
|
||||||
{
|
{
|
||||||
LOG.warn("No Next protocol '{}' for {}",_next,getEndPoint());
|
LOG.warn("No Next protocol '{}' for {}", _next, getEndPoint());
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.warn("Next protocol '{}' for {} r={} l={}",_next,getEndPoint(),remote,local);
|
LOG.warn("Next protocol '{}' for {} r={} l={}", _next, getEndPoint(), remote, local);
|
||||||
|
|
||||||
EndPoint endPoint = new ProxyEndPoint(getEndPoint(),remote,local);
|
EndPoint endPoint = new ProxyEndPoint(getEndPoint(), remote, local);
|
||||||
Connection newConnection = connectionFactory.newConnection(_connector, endPoint);
|
Connection newConnection = connectionFactory.newConnection(_connector, endPoint);
|
||||||
endPoint.upgrade(newConnection);
|
endPoint.upgrade(newConnection);
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.warn("PROXY error for "+getEndPoint(),x);
|
LOG.warn("PROXY error for " + getEndPoint(), x);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum Family
|
||||||
|
{
|
||||||
|
UNSPEC, INET, INET6, UNIX
|
||||||
|
}
|
||||||
|
|
||||||
enum Family { UNSPEC, INET, INET6, UNIX };
|
private enum Transport
|
||||||
enum Transport { UNSPEC, STREAM, DGRAM };
|
{
|
||||||
private static final byte[] MAGIC = new byte[]{0x0D,0x0A,0x0D,0x0A,0x00,0x0D,0x0A,0x51,0x55,0x49,0x54,0x0A};
|
UNSPEC, STREAM, DGRAM
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final byte[] MAGIC = new byte[]{0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A};
|
||||||
|
|
||||||
public class ProxyProtocolV2Connection extends AbstractConnection
|
public class ProxyProtocolV2Connection extends AbstractConnection
|
||||||
{
|
{
|
||||||
|
@ -336,18 +339,17 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
private final int _length;
|
private final int _length;
|
||||||
private final ByteBuffer _buffer;
|
private final ByteBuffer _buffer;
|
||||||
|
|
||||||
protected ProxyProtocolV2Connection(EndPoint endp, Connector connector, String next,ByteBuffer buffer)
|
protected ProxyProtocolV2Connection(EndPoint endp, Connector connector, String next, ByteBuffer buffer) throws IOException
|
||||||
throws IOException
|
|
||||||
{
|
{
|
||||||
super(endp,connector.getExecutor());
|
super(endp, connector.getExecutor());
|
||||||
_connector=connector;
|
_connector = connector;
|
||||||
_next=next;
|
_next = next;
|
||||||
|
|
||||||
if (buffer.remaining()!=16)
|
if (buffer.remaining() != 16)
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("PROXYv2 header {} for {}",BufferUtil.toHexSummary(buffer),this);
|
LOG.debug("PROXYv2 header {} for {}", BufferUtil.toHexSummary(buffer), this);
|
||||||
|
|
||||||
// struct proxy_hdr_v2 {
|
// struct proxy_hdr_v2 {
|
||||||
// uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
|
// uint8_t sig[12]; /* hex 0D 0A 0D 0A 00 0D 0A 51 55 49 54 0A */
|
||||||
|
@ -355,51 +357,67 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
// uint8_t fam; /* protocol family and address */
|
// uint8_t fam; /* protocol family and address */
|
||||||
// uint16_t len; /* number of following bytes part of the header */
|
// uint16_t len; /* number of following bytes part of the header */
|
||||||
// };
|
// };
|
||||||
for (int i=0;i<MAGIC.length;i++)
|
for (byte magic : MAGIC)
|
||||||
if (buffer.get()!=MAGIC[i])
|
{
|
||||||
|
if (buffer.get() != magic)
|
||||||
throw new IOException("Bad PROXY protocol v2 signature");
|
throw new IOException("Bad PROXY protocol v2 signature");
|
||||||
|
}
|
||||||
|
|
||||||
int versionAndCommand = 0xff & buffer.get();
|
int versionAndCommand = 0xff & buffer.get();
|
||||||
if ((versionAndCommand&0xf0) != 0x20)
|
if ((versionAndCommand & 0xf0) != 0x20)
|
||||||
throw new IOException("Bad PROXY protocol v2 version");
|
throw new IOException("Bad PROXY protocol v2 version");
|
||||||
_local=(versionAndCommand&0xf)==0x00;
|
_local = (versionAndCommand & 0xf) == 0x00;
|
||||||
|
|
||||||
int transportAndFamily = 0xff & buffer.get();
|
int transportAndFamily = 0xff & buffer.get();
|
||||||
switch(transportAndFamily>>4)
|
switch (transportAndFamily >> 4)
|
||||||
{
|
{
|
||||||
case 0: _family=Family.UNSPEC; break;
|
case 0:
|
||||||
case 1: _family=Family.INET; break;
|
_family = Family.UNSPEC;
|
||||||
case 2: _family=Family.INET6; break;
|
break;
|
||||||
case 3: _family=Family.UNIX; break;
|
case 1:
|
||||||
|
_family = Family.INET;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_family = Family.INET6;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
_family = Family.UNIX;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IOException("Bad PROXY protocol v2 family");
|
throw new IOException("Bad PROXY protocol v2 family");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(0xf&transportAndFamily)
|
switch (0xf & transportAndFamily)
|
||||||
{
|
{
|
||||||
case 0: _transport=Transport.UNSPEC; break;
|
case 0:
|
||||||
case 1: _transport=Transport.STREAM; break;
|
_transport = Transport.UNSPEC;
|
||||||
case 2: _transport=Transport.DGRAM; break;
|
break;
|
||||||
|
case 1:
|
||||||
|
_transport = Transport.STREAM;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_transport = Transport.DGRAM;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IOException("Bad PROXY protocol v2 family");
|
throw new IOException("Bad PROXY protocol v2 family");
|
||||||
}
|
}
|
||||||
|
|
||||||
_length = buffer.getChar();
|
_length = buffer.getChar();
|
||||||
|
|
||||||
if (!_local && (_family==Family.UNSPEC || _family==Family.UNIX || _transport!=Transport.STREAM))
|
if (!_local && (_family == Family.UNSPEC || _family == Family.UNIX || _transport != Transport.STREAM))
|
||||||
throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x",versionAndCommand,transportAndFamily));
|
throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x", versionAndCommand, transportAndFamily));
|
||||||
|
|
||||||
if (_length>_maxProxyHeader)
|
if (_length > getMaxProxyHeader())
|
||||||
throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x,0x%x",versionAndCommand,transportAndFamily,_length));
|
throw new IOException(String.format("Unsupported PROXY protocol v2 mode 0x%x,0x%x,0x%x", versionAndCommand, transportAndFamily, _length));
|
||||||
|
|
||||||
_buffer = _length>0?BufferUtil.allocate(_length):BufferUtil.EMPTY_BUFFER;
|
_buffer = _length > 0 ? BufferUtil.allocate(_length) : BufferUtil.EMPTY_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen()
|
public void onOpen()
|
||||||
{
|
{
|
||||||
super.onOpen();
|
super.onOpen();
|
||||||
if (_buffer.remaining()==_length)
|
if (_buffer.remaining() == _length)
|
||||||
next();
|
next();
|
||||||
else
|
else
|
||||||
fillInterested();
|
fillInterested();
|
||||||
|
@ -410,48 +428,46 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while(_buffer.remaining()<_length)
|
while (_buffer.remaining() < _length)
|
||||||
{
|
{
|
||||||
// Read data
|
// Read data
|
||||||
int fill=getEndPoint().fill(_buffer);
|
int fill = getEndPoint().fill(_buffer);
|
||||||
if (fill<0)
|
if (fill < 0)
|
||||||
{
|
{
|
||||||
getEndPoint().shutdownOutput();
|
getEndPoint().shutdownOutput();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fill==0)
|
if (fill == 0)
|
||||||
{
|
{
|
||||||
fillInterested();
|
fillInterested();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
catch (Throwable x)
|
catch (Throwable x)
|
||||||
{
|
{
|
||||||
LOG.warn("PROXY error for "+getEndPoint(),x);
|
LOG.warn("PROXY error for " + getEndPoint(), x);
|
||||||
close();
|
close();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void next()
|
private void next()
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("PROXYv2 next {} from {} for {}",_next,BufferUtil.toHexSummary(_buffer),this);
|
LOG.debug("PROXYv2 next {} from {} for {}", _next, BufferUtil.toHexSummary(_buffer), this);
|
||||||
|
|
||||||
// Create the next protocol
|
// Create the next protocol
|
||||||
ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next);
|
ConnectionFactory connectionFactory = _connector.getConnectionFactory(_next);
|
||||||
if (connectionFactory == null)
|
if (connectionFactory == null)
|
||||||
{
|
{
|
||||||
LOG.info("Next protocol '{}' for {}",_next,getEndPoint());
|
LOG.info("Next protocol '{}' for {}", _next, getEndPoint());
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we need to wrap the endpoint?
|
// Do we need to wrap the endpoint?
|
||||||
EndPoint endPoint=getEndPoint();
|
EndPoint endPoint = getEndPoint();
|
||||||
if (!_local)
|
if (!_local)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -461,24 +477,23 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
int sp;
|
int sp;
|
||||||
int dp;
|
int dp;
|
||||||
|
|
||||||
switch(_family)
|
switch (_family)
|
||||||
{
|
{
|
||||||
case INET:
|
case INET:
|
||||||
{
|
{
|
||||||
byte[] addr=new byte[4];
|
byte[] addr = new byte[4];
|
||||||
_buffer.get(addr);
|
_buffer.get(addr);
|
||||||
src = Inet4Address.getByAddress(addr);
|
src = Inet4Address.getByAddress(addr);
|
||||||
_buffer.get(addr);
|
_buffer.get(addr);
|
||||||
dst = Inet4Address.getByAddress(addr);
|
dst = Inet4Address.getByAddress(addr);
|
||||||
sp = _buffer.getChar();
|
sp = _buffer.getChar();
|
||||||
dp = _buffer.getChar();
|
dp = _buffer.getChar();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case INET6:
|
case INET6:
|
||||||
{
|
{
|
||||||
byte[] addr=new byte[16];
|
byte[] addr = new byte[16];
|
||||||
_buffer.get(addr);
|
_buffer.get(addr);
|
||||||
src = Inet6Address.getByAddress(addr);
|
src = Inet6Address.getByAddress(addr);
|
||||||
_buffer.get(addr);
|
_buffer.get(addr);
|
||||||
|
@ -492,16 +507,14 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Extract Addresses
|
// Extract Addresses
|
||||||
InetSocketAddress remote=new InetSocketAddress(src,sp);
|
InetSocketAddress remote = new InetSocketAddress(src, sp);
|
||||||
InetSocketAddress local =new InetSocketAddress(dst,dp);
|
InetSocketAddress local = new InetSocketAddress(dst, dp);
|
||||||
ProxyEndPoint proxyEndPoint = new ProxyEndPoint(endPoint,remote,local);
|
ProxyEndPoint proxyEndPoint = new ProxyEndPoint(endPoint, remote, local);
|
||||||
endPoint = proxyEndPoint;
|
endPoint = proxyEndPoint;
|
||||||
|
|
||||||
|
|
||||||
// Any additional info?
|
// Any additional info?
|
||||||
while(_buffer.hasRemaining())
|
while (_buffer.hasRemaining())
|
||||||
{
|
{
|
||||||
int type = 0xff & _buffer.get();
|
int type = 0xff & _buffer.get();
|
||||||
int length = _buffer.getShort();
|
int length = _buffer.getShort();
|
||||||
|
@ -509,10 +522,10 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
_buffer.get(value);
|
_buffer.get(value);
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug(String.format("T=%x L=%d V=%s for %s",type,length,TypeUtil.toHexString(value),this));
|
LOG.debug(String.format("T=%x L=%d V=%s for %s", type, length, TypeUtil.toHexString(value), this));
|
||||||
|
|
||||||
// TODO interpret these values
|
// TODO interpret these values
|
||||||
switch(type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 0x01: // PP2_TYPE_ALPN
|
case 0x01: // PP2_TYPE_ALPN
|
||||||
break;
|
break;
|
||||||
|
@ -520,23 +533,22 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
break;
|
break;
|
||||||
case 0x20: // PP2_TYPE_SSL
|
case 0x20: // PP2_TYPE_SSL
|
||||||
{
|
{
|
||||||
int i=0;
|
int i = 0;
|
||||||
int client = 0xff & value[i++];
|
int client = 0xff & value[i++];
|
||||||
int verify = ((0xff & value[i++])<<24) + ((0xff & value[i++])<<16) + ((0xff & value[i++])<<8) + (0xff&value[i++]);
|
while (i < value.length)
|
||||||
while(i<value.length)
|
|
||||||
{
|
{
|
||||||
int ssl_type = 0xff & value[i++];
|
int ssl_type = 0xff & value[i++];
|
||||||
int ssl_length = (0xff & value[i++])*0x100 + (0xff&value[i++]);
|
int ssl_length = (0xff & value[i++]) * 0x100 + (0xff & value[i++]);
|
||||||
byte[] ssl_val = new byte[ssl_length];
|
byte[] ssl_val = new byte[ssl_length];
|
||||||
System.arraycopy(value,i,ssl_val,0,ssl_length);
|
System.arraycopy(value, i, ssl_val, 0, ssl_length);
|
||||||
i+=ssl_length;
|
i += ssl_length;
|
||||||
|
|
||||||
switch(ssl_type)
|
switch (ssl_type)
|
||||||
{
|
{
|
||||||
case 0x21: // PP2_TYPE_SSL_VERSION
|
case 0x21: // PP2_TYPE_SSL_VERSION
|
||||||
String version=new String(ssl_val,0,ssl_length,StandardCharsets.ISO_8859_1);
|
String version = new String(ssl_val, 0, ssl_length, StandardCharsets.ISO_8859_1);
|
||||||
if (client==1)
|
if (client == 1)
|
||||||
proxyEndPoint.setAttribute(TLS_VERSION,version);
|
proxyEndPoint.setAttribute(TLS_VERSION, version);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -557,11 +569,10 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
LOG.debug("{} {}",getEndPoint(),proxyEndPoint.toString());
|
LOG.debug("{} {}", getEndPoint(), proxyEndPoint.toString());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOG.warn(e);
|
LOG.warn(e);
|
||||||
}
|
}
|
||||||
|
@ -572,7 +583,6 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class ProxyEndPoint extends AttributesMap implements EndPoint
|
public static class ProxyEndPoint extends AttributesMap implements EndPoint
|
||||||
{
|
{
|
||||||
private final EndPoint _endp;
|
private final EndPoint _endp;
|
||||||
|
@ -581,9 +591,9 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
|
|
||||||
public ProxyEndPoint(EndPoint endp, InetSocketAddress remote, InetSocketAddress local)
|
public ProxyEndPoint(EndPoint endp, InetSocketAddress remote, InetSocketAddress local)
|
||||||
{
|
{
|
||||||
_endp=endp;
|
_endp = endp;
|
||||||
_remote=remote;
|
_remote = remote;
|
||||||
_local=local;
|
_local = local;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -691,7 +701,7 @@ public class ProxyConnectionFactory extends AbstractConnectionFactory
|
||||||
@Override
|
@Override
|
||||||
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
|
public void write(Callback callback, ByteBuffer... buffers) throws WritePendingException
|
||||||
{
|
{
|
||||||
_endp.write(callback,buffers);
|
_endp.write(callback, buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue