Overall clean-up on socksx package
- SocksV[45] -> Socks[45] - Make encodeAsByteBuf package private with some hassle - Split SocksMessageEncoder into Socks4MessageEncoder and Socks5MessageEncoder, and remove the original - Remove lazy singleton instantiation; we don't need it. - Remove the deprecated methods - Fix Javadoc errors
This commit is contained in:
parent
1a05004523
commit
fc1429c00c
@ -18,4 +18,3 @@
|
|||||||
* Encoder, decoder and their related message types for Socks.
|
* Encoder, decoder and their related message types for Socks.
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socks;
|
package io.netty.handler.codec.socks;
|
||||||
// TODO: Combine decoders into one.
|
|
||||||
|
@ -15,16 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx;
|
package io.netty.handler.codec.socksx;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksMessage, providing common properties for
|
* An abstract class that defines a SocksMessage, providing common properties for
|
||||||
* {@link SocksV5Request} and {@link SocksV5Response}.
|
* {@link SocksRequest} and {@link SocksResponse}.
|
||||||
*
|
|
||||||
* @see SocksV5Request
|
|
||||||
* @see SocksV5Response
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class SocksMessage {
|
public abstract class SocksMessage {
|
||||||
private final SocksMessageType type;
|
private final SocksMessageType type;
|
||||||
private final SocksProtocolVersion protocolVersion;
|
private final SocksProtocolVersion protocolVersion;
|
||||||
@ -57,10 +51,4 @@ public abstract class SocksMessage {
|
|||||||
public SocksProtocolVersion protocolVersion() {
|
public SocksProtocolVersion protocolVersion() {
|
||||||
return protocolVersion;
|
return protocolVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Do not use; this method was intended for an internal use only.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public abstract void encodeAsByteBuf(ByteBuf byteBuf);
|
|
||||||
}
|
}
|
||||||
|
@ -27,14 +27,6 @@ public enum SocksProtocolVersion {
|
|||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use {@link #valueOf(byte)} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public static SocksProtocolVersion fromByte(byte b) {
|
|
||||||
return valueOf(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SocksProtocolVersion valueOf(byte b) {
|
public static SocksProtocolVersion valueOf(byte b) {
|
||||||
for (SocksProtocolVersion code : values()) {
|
for (SocksProtocolVersion code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
|
@ -16,18 +16,12 @@
|
|||||||
package io.netty.handler.codec.socksx;
|
package io.netty.handler.codec.socksx;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.handler.codec.socksx.v4.Socks4Request;
|
||||||
|
import io.netty.handler.codec.socksx.v5.Socks5Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksRequest, providing common properties for
|
* An abstract class that defines a SOCKS request, providing common properties for
|
||||||
* {@link SocksV5InitRequest},
|
* {@link Socks4Request} and {@link Socks5Request}.
|
||||||
* {@link SocksV5AuthRequest},
|
|
||||||
* {@link SocksV5CmdRequest}
|
|
||||||
* and {@link UnknownSocksV5Request}.
|
|
||||||
*
|
|
||||||
* @see io.netty.handler.codec.socks.SocksInitRequest
|
|
||||||
* @see io.netty.handler.codec.socks.SocksAuthRequest
|
|
||||||
* @see io.netty.handler.codec.socks.SocksCmdRequest
|
|
||||||
* @see io.netty.handler.codec.socks.UnknownSocksRequest
|
|
||||||
*/
|
*/
|
||||||
public abstract class SocksRequest extends SocksMessage {
|
public abstract class SocksRequest extends SocksMessage {
|
||||||
|
|
||||||
|
@ -15,6 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx;
|
package io.netty.handler.codec.socksx;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.socksx.v4.Socks4Response;
|
||||||
|
import io.netty.handler.codec.socksx.v5.Socks5Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract class that defines a SOCKS response, providing common properties for
|
||||||
|
* {@link Socks4Response} and {@link Socks5Response}.
|
||||||
|
*/
|
||||||
public abstract class SocksResponse extends SocksMessage {
|
public abstract class SocksResponse extends SocksMessage {
|
||||||
protected SocksResponse(SocksProtocolVersion protocolVersion) {
|
protected SocksResponse(SocksProtocolVersion protocolVersion) {
|
||||||
super(protocolVersion, SocksMessageType.RESPONSE);
|
super(protocolVersion, SocksMessageType.RESPONSE);
|
||||||
|
@ -15,6 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoder, decoder and their related message types for Socks.
|
* Encoder, decoder and their related message types for SOCKS protocol.
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx;
|
package io.netty.handler.codec.socksx;
|
||||||
|
@ -18,26 +18,24 @@ package io.netty.handler.codec.socksx.v4;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.NetUtil;
|
import io.netty.util.NetUtil;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
|
||||||
|
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An socksv4a cmd request.
|
* An socksv4a cmd request.
|
||||||
*
|
*
|
||||||
* @see SocksV4Response
|
* @see Socks4Response
|
||||||
* @see SocksV4CmdRequestDecoder
|
* @see Socks4CmdRequestDecoder
|
||||||
*/
|
*/
|
||||||
|
public final class Socks4CmdRequest extends Socks4Request {
|
||||||
public final class SocksV4CmdRequest extends SocksV4Request {
|
|
||||||
private final String userId;
|
private final String userId;
|
||||||
private final SocksV4CmdType cmdType;
|
private final Socks4CmdType cmdType;
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
private static final byte[] IPv4_DOMAIN_MARKER = {0x00, 0x00, 0x00, 0x01};
|
private static final byte[] IPv4_DOMAIN_MARKER = {0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
public SocksV4CmdRequest(String userId, SocksV4CmdType cmdType, String host, int port) {
|
public Socks4CmdRequest(String userId, Socks4CmdType cmdType, String host, int port) {
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
throw new NullPointerException("username");
|
throw new NullPointerException("username");
|
||||||
}
|
}
|
||||||
@ -56,48 +54,48 @@ public final class SocksV4CmdRequest extends SocksV4Request {
|
|||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocksV4CmdRequest(SocksV4CmdType cmdType, String host, int port) {
|
public Socks4CmdRequest(Socks4CmdType cmdType, String host, int port) {
|
||||||
this("", cmdType, host, port);
|
this("", cmdType, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV4CmdType} of this {@link SocksV4Request}
|
* Returns the {@link Socks4CmdType} of this {@link Socks4Request}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV4CmdType} of this {@link SocksV4Request}
|
* @return The {@link Socks4CmdType} of this {@link Socks4Request}
|
||||||
*/
|
*/
|
||||||
public SocksV4CmdType cmdType() {
|
public Socks4CmdType cmdType() {
|
||||||
return cmdType;
|
return cmdType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns host that is used as a parameter in {@link SocksV4CmdType}
|
* Returns host that is used as a parameter in {@link Socks4CmdType}
|
||||||
*
|
*
|
||||||
* @return host that is used as a parameter in {@link SocksV4CmdType}
|
* @return host that is used as a parameter in {@link Socks4CmdType}
|
||||||
*/
|
*/
|
||||||
public String host() {
|
public String host() {
|
||||||
return IDN.toUnicode(host);
|
return IDN.toUnicode(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns userId that is used as a parameter in {@link SocksV4CmdType}
|
* Returns userId that is used as a parameter in {@link Socks4CmdType}
|
||||||
*
|
*
|
||||||
* @return userId that is used as a parameter in {@link SocksV4CmdType}
|
* @return userId that is used as a parameter in {@link Socks4CmdType}
|
||||||
*/
|
*/
|
||||||
public String userId() {
|
public String userId() {
|
||||||
return userId;
|
return userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns port that is used as a parameter in {@link SocksV4CmdType}
|
* Returns port that is used as a parameter in {@link Socks4CmdType}
|
||||||
*
|
*
|
||||||
* @return port that is used as a parameter in {@link SocksV4CmdType}
|
* @return port that is used as a parameter in {@link Socks4CmdType}
|
||||||
*/
|
*/
|
||||||
public int port() {
|
public int port() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(protocolVersion().byteValue());
|
byteBuf.writeByte(protocolVersion().byteValue());
|
||||||
byteBuf.writeByte(cmdType.byteValue());
|
byteBuf.writeByte(cmdType.byteValue());
|
||||||
byteBuf.writeShort(port);
|
byteBuf.writeShort(port);
|
@ -19,29 +19,27 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequestDecoder.State;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdRequestDecoder.State;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV4CmdRequest}.
|
* Decodes {@link ByteBuf}s into {@link Socks4CmdRequest}.
|
||||||
* Before returning SocksRequest decoder removes itself from pipeline.
|
* Before returning SocksRequest decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> {
|
public class Socks4CmdRequestDecoder extends ReplayingDecoder<State> {
|
||||||
private static final String name = "SOCKS_CMD_REQUEST_DECODER";
|
|
||||||
|
|
||||||
private SocksProtocolVersion version;
|
private SocksProtocolVersion version;
|
||||||
private SocksV4CmdType cmdType;
|
private Socks4CmdType cmdType;
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private byte reserved;
|
private byte reserved;
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
private String userId;
|
private String userId;
|
||||||
private SocksV4Request msg = UnknownSocksV4Request.getInstance();
|
private Socks4Request msg = UnknownSocks4Request.INSTANCE;
|
||||||
|
|
||||||
public SocksV4CmdRequestDecoder() {
|
public Socks4CmdRequestDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,9 +54,9 @@ public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
checkpoint(State.READ_CMD_HEADER);
|
checkpoint(State.READ_CMD_HEADER);
|
||||||
}
|
}
|
||||||
case READ_CMD_HEADER: {
|
case READ_CMD_HEADER: {
|
||||||
cmdType = SocksV4CmdType.valueOf(byteBuf.readByte());
|
cmdType = Socks4CmdType.valueOf(byteBuf.readByte());
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
host = SocksV4CommonUtils.intToIp(byteBuf.readInt());
|
host = Socks4CommonUtils.intToIp(byteBuf.readInt());
|
||||||
checkpoint(State.READ_CMD_USERID);
|
checkpoint(State.READ_CMD_USERID);
|
||||||
}
|
}
|
||||||
case READ_CMD_USERID: {
|
case READ_CMD_USERID: {
|
||||||
@ -67,17 +65,17 @@ public class SocksV4CmdRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
}
|
}
|
||||||
case READ_CMD_DOMAIN: {
|
case READ_CMD_DOMAIN: {
|
||||||
// Check for Socks4a protocol marker 0,0,0,x
|
// Check for Socks4a protocol marker 0,0,0,x
|
||||||
if (!host.equals("0.0.0.0") && host.startsWith("0.0.0.")) {
|
if (!"0.0.0.0".equals(host) && host.startsWith("0.0.0.")) {
|
||||||
host = readNullTerminatedString(byteBuf);
|
host = readNullTerminatedString(byteBuf);
|
||||||
}
|
}
|
||||||
msg = new SocksV4CmdRequest(userId, cmdType, host, port);
|
msg = new Socks4CmdRequest(userId, cmdType, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.pipeline().remove(this);
|
ctx.pipeline().remove(this);
|
||||||
out.add(msg);
|
out.add(msg);
|
||||||
}
|
}
|
||||||
private static String readNullTerminatedString(ByteBuf byteBuf) throws Exception {
|
private static String readNullTerminatedString(ByteBuf byteBuf) throws Exception {
|
||||||
byte NULL_BYTE = (byte) 0x00;
|
byte NULL_BYTE = 0x00;
|
||||||
// Could be used for DoS
|
// Could be used for DoS
|
||||||
String string = byteBuf.readBytes(byteBuf.bytesBefore(NULL_BYTE)).toString(CharsetUtil.US_ASCII);
|
String string = byteBuf.readBytes(byteBuf.bytesBefore(NULL_BYTE)).toString(CharsetUtil.US_ASCII);
|
||||||
// Read NULL-byte
|
// Read NULL-byte
|
@ -23,18 +23,18 @@ import java.net.IDN;
|
|||||||
/**
|
/**
|
||||||
* A socks cmd response.
|
* A socks cmd response.
|
||||||
*
|
*
|
||||||
* @see SocksV4CmdRequest
|
* @see Socks4CmdRequest
|
||||||
* @see SocksV4CmdResponseDecoder
|
* @see Socks4CmdResponseDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV4CmdResponse extends SocksV4Response {
|
public final class Socks4CmdResponse extends Socks4Response {
|
||||||
private final SocksV4CmdStatus cmdStatus;
|
private final Socks4CmdStatus cmdStatus;
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
// All arrays are initialized on construction time to 0/false/null remove array Initialization
|
// All arrays are initialized on construction time to 0/false/null remove array Initialization
|
||||||
private static final byte[] IPv4_HOSTNAME_ZEROED = { 0x00, 0x00, 0x00, 0x00 };
|
private static final byte[] IPv4_HOSTNAME_ZEROED = { 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
public SocksV4CmdResponse(SocksV4CmdStatus cmdStatus) {
|
public Socks4CmdResponse(Socks4CmdStatus cmdStatus) {
|
||||||
this(cmdStatus, null, 0);
|
this(cmdStatus, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,13 +44,13 @@ public final class SocksV4CmdResponse extends SocksV4Response {
|
|||||||
* @param cmdStatus status of the response
|
* @param cmdStatus status of the response
|
||||||
* @param host host (BND.ADDR field) is address that server used when connecting to the target host.
|
* @param host host (BND.ADDR field) is address that server used when connecting to the target host.
|
||||||
* When null a value of 4/8 0x00 octets will be used for IPv4/IPv6 and a single 0x00 byte will be
|
* When null a value of 4/8 0x00 octets will be used for IPv4/IPv6 and a single 0x00 byte will be
|
||||||
* used for domain addressType. Value is converted to ASCII using {@link java.net.IDN#toASCII(String)}.
|
* used for domain addressType. Value is converted to ASCII using {@link IDN#toASCII(String)}.
|
||||||
* @param port port (BND.PORT field) that the server assigned to connect to the target host
|
* @param port port (BND.PORT field) that the server assigned to connect to the target host
|
||||||
* @throws NullPointerException in case cmdStatus or addressType are missing
|
* @throws NullPointerException in case cmdStatus or addressType are missing
|
||||||
* @throws IllegalArgumentException in case host or port cannot be validated
|
* @throws IllegalArgumentException in case host or port cannot be validated
|
||||||
* @see java.net.IDN#toASCII(String)
|
* @see IDN#toASCII(String)
|
||||||
*/
|
*/
|
||||||
public SocksV4CmdResponse(SocksV4CmdStatus cmdStatus, String host, int port) {
|
public Socks4CmdResponse(Socks4CmdStatus cmdStatus, String host, int port) {
|
||||||
if (cmdStatus == null) {
|
if (cmdStatus == null) {
|
||||||
throw new NullPointerException("cmdStatus");
|
throw new NullPointerException("cmdStatus");
|
||||||
}
|
}
|
||||||
@ -68,20 +68,20 @@ public final class SocksV4CmdResponse extends SocksV4Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV4CmdStatus} of this {@link SocksV4Response}
|
* Returns the {@link Socks4CmdStatus} of this {@link Socks4Response}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV4CmdStatus} of this {@link SocksV4Response}
|
* @return The {@link Socks4CmdStatus} of this {@link Socks4Response}
|
||||||
*/
|
*/
|
||||||
public SocksV4CmdStatus cmdStatus() {
|
public Socks4CmdStatus cmdStatus() {
|
||||||
return cmdStatus;
|
return cmdStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns host that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}.
|
* Returns host that is used as a parameter in {@link Socks4CmdType}.
|
||||||
* Host (BND.ADDR field in response) is address that server used when connecting to the target host.
|
* Host (BND.ADDR field in response) is address that server used when connecting to the target host.
|
||||||
* This is typically different from address which client uses to connect to the SOCKS server.
|
* This is typically different from address which client uses to connect to the SOCKS server.
|
||||||
*
|
*
|
||||||
* @return host that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}
|
* @return host that is used as a parameter in {@link Socks4CmdType}
|
||||||
* or null when there was no host specified during response construction
|
* or null when there was no host specified during response construction
|
||||||
*/
|
*/
|
||||||
public String host() {
|
public String host() {
|
||||||
@ -93,10 +93,10 @@ public final class SocksV4CmdResponse extends SocksV4Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns port that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}.
|
* Returns port that is used as a parameter in {@link Socks4CmdType}.
|
||||||
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
|
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
|
||||||
*
|
*
|
||||||
* @return port that is used as a parameter in {@link io.netty.handler.codec.socks.v4.SocksV4CmdType}
|
* @return port that is used as a parameter in {@link Socks4CmdType}
|
||||||
*/
|
*/
|
||||||
public int port() {
|
public int port() {
|
||||||
return port;
|
return port;
|
@ -18,27 +18,23 @@ package io.netty.handler.codec.socksx.v4;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socks.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdResponseDecoder.State;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdResponseDecoder.State;
|
|
||||||
import io.netty.util.CharsetUtil;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV4CmdResponse}.
|
* Decodes {@link ByteBuf}s into {@link Socks4CmdResponse}.
|
||||||
* Before returning SocksResponse decoder removes itself from pipeline.
|
* Before returning SocksResponse decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV4CmdResponseDecoder extends ReplayingDecoder<State> {
|
public class Socks4CmdResponseDecoder extends ReplayingDecoder<State> {
|
||||||
private static final String name = "SOCKS_CMD_RESPONSE_DECODER";
|
|
||||||
|
|
||||||
private SocksProtocolVersion version;
|
private Socks4CmdStatus cmdStatus;
|
||||||
private SocksV4CmdStatus cmdStatus;
|
|
||||||
|
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
private SocksV4Response msg = UnknownSocksV4Response.getInstance();
|
private Socks4Response msg = UnknownSocks4Response.INSTANCE;
|
||||||
|
|
||||||
public SocksV4CmdResponseDecoder() {
|
public Socks4CmdResponseDecoder() {
|
||||||
super(State.CHECK_NULL_BYTE);
|
super(State.CHECK_NULL_BYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,13 +48,13 @@ public class SocksV4CmdResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
checkpoint(State.READ_CMD_HEADER);
|
checkpoint(State.READ_CMD_HEADER);
|
||||||
}
|
}
|
||||||
case READ_CMD_HEADER: {
|
case READ_CMD_HEADER: {
|
||||||
cmdStatus = SocksV4CmdStatus.valueOf(byteBuf.readByte());
|
cmdStatus = Socks4CmdStatus.valueOf(byteBuf.readByte());
|
||||||
checkpoint(State.READ_CMD_ADDRESS);
|
checkpoint(State.READ_CMD_ADDRESS);
|
||||||
}
|
}
|
||||||
case READ_CMD_ADDRESS: {
|
case READ_CMD_ADDRESS: {
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
host = SocksV4CommonUtils.intToIp(byteBuf.readInt());
|
host = Socks4CommonUtils.intToIp(byteBuf.readInt());
|
||||||
msg = new SocksV4CmdResponse(cmdStatus, host, port);
|
msg = new Socks4CmdResponse(cmdStatus, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.pipeline().remove(this);
|
ctx.pipeline().remove(this);
|
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
public enum SocksV4CmdStatus {
|
public enum Socks4CmdStatus {
|
||||||
SUCCESS((byte) 0x5a),
|
SUCCESS((byte) 0x5a),
|
||||||
REJECTED_OR_FAILED((byte) 0x5b),
|
REJECTED_OR_FAILED((byte) 0x5b),
|
||||||
IDENTD_UNREACHABLE((byte) 0x5c),
|
IDENTD_UNREACHABLE((byte) 0x5c),
|
||||||
@ -24,12 +24,12 @@ public enum SocksV4CmdStatus {
|
|||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV4CmdStatus(byte b) {
|
Socks4CmdStatus(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV4CmdStatus valueOf(byte b) {
|
public static Socks4CmdStatus valueOf(byte b) {
|
||||||
for (SocksV4CmdStatus code : values()) {
|
for (Socks4CmdStatus code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -15,19 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
public enum SocksV4CmdType {
|
public enum Socks4CmdType {
|
||||||
CONNECT((byte) 0x01),
|
CONNECT((byte) 0x01),
|
||||||
BIND((byte) 0x02),
|
BIND((byte) 0x02),
|
||||||
UNKNOWN((byte) 0xff);
|
UNKNOWN((byte) 0xff);
|
||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV4CmdType(byte b) {
|
Socks4CmdType(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV4CmdType valueOf(byte b) {
|
public static Socks4CmdType valueOf(byte b) {
|
||||||
for (SocksV4CmdType code : values()) {
|
for (Socks4CmdType code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -16,7 +16,8 @@
|
|||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
public final class SocksV4CommonUtils {
|
final class Socks4CommonUtils {
|
||||||
|
|
||||||
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
|
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
|
||||||
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
|
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
|
||||||
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
|
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
|
||||||
@ -25,7 +26,7 @@ public final class SocksV4CommonUtils {
|
|||||||
/**
|
/**
|
||||||
* A constructor to stop this class being constructed.
|
* A constructor to stop this class being constructed.
|
||||||
*/
|
*/
|
||||||
private SocksV4CommonUtils() {
|
private Socks4CommonUtils() {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import io.netty.handler.codec.socksx.SocksMessage;
|
||||||
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes a {@link Socks4Request} and {@link Socks4Response} into a {@link ByteBuf}.
|
||||||
|
*/
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
public final class Socks4MessageEncoder extends MessageToByteEncoder<SocksMessage> {
|
||||||
|
|
||||||
|
public static final Socks4MessageEncoder INSTANCE = new Socks4MessageEncoder();
|
||||||
|
|
||||||
|
private Socks4MessageEncoder() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptOutboundMessage(Object msg) throws Exception {
|
||||||
|
return super.acceptOutboundMessage(msg) &&
|
||||||
|
((SocksMessage) msg).protocolVersion() == SocksProtocolVersion.SOCKS4a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception {
|
||||||
|
if (msg instanceof Socks4Response) {
|
||||||
|
((Socks4Response) msg).encodeAsByteBuf(out);
|
||||||
|
} else if (msg instanceof Socks4Request) {
|
||||||
|
((Socks4Request) msg).encodeAsByteBuf(out);
|
||||||
|
} else {
|
||||||
|
// Should not reach here.
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,20 +15,26 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.socksx.SocksMessageType;
|
import io.netty.handler.codec.socks.SocksMessage;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.SocksRequest;
|
import io.netty.handler.codec.socksx.SocksRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksRequest, providing common properties for
|
* An abstract class that defines a SocksRequest, providing common properties for
|
||||||
* {@link SocksV4CmdRequest}.
|
* {@link Socks4CmdRequest}.
|
||||||
*
|
*
|
||||||
* @see SocksV4CmdRequest
|
* @see Socks4CmdRequest
|
||||||
* @see UnknownSocksV4Request
|
* @see UnknownSocks4Request
|
||||||
*/
|
*/
|
||||||
public abstract class SocksV4Request extends SocksRequest {
|
public abstract class Socks4Request extends SocksRequest {
|
||||||
protected SocksV4Request() {
|
protected Socks4Request() {
|
||||||
super(SocksProtocolVersion.SOCKS4a);
|
super(SocksProtocolVersion.SOCKS4a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
|
||||||
|
* because we do not want to expose this method to users.
|
||||||
|
*/
|
||||||
|
abstract void encodeAsByteBuf(ByteBuf byteBuf);
|
||||||
}
|
}
|
@ -15,22 +15,27 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.socksx.SocksMessageType;
|
import io.netty.handler.codec.socks.SocksMessage;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.SocksResponse;
|
import io.netty.handler.codec.socksx.SocksResponse;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5ResponseType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksResponse, providing common properties for
|
* An abstract class that defines a SocksResponse, providing common properties for
|
||||||
* {@link SocksV4CmdResponse}.
|
* {@link Socks4CmdResponse}.
|
||||||
*
|
*
|
||||||
* @see SocksV4CmdResponse
|
* @see Socks4CmdResponse
|
||||||
* @see UnknownSocksV4Response
|
* @see UnknownSocks4Response
|
||||||
*/
|
*/
|
||||||
public abstract class SocksV4Response extends SocksResponse {
|
public abstract class Socks4Response extends SocksResponse {
|
||||||
|
|
||||||
protected SocksV4Response() {
|
protected Socks4Response() {
|
||||||
super(SocksProtocolVersion.SOCKS4a);
|
super(SocksProtocolVersion.SOCKS4a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
|
||||||
|
* because we do not want to expose this method to users.
|
||||||
|
*/
|
||||||
|
abstract void encodeAsByteBuf(ByteBuf byteBuf);
|
||||||
}
|
}
|
@ -20,23 +20,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
/**
|
/**
|
||||||
* An unknown socks request.
|
* An unknown socks request.
|
||||||
*
|
*
|
||||||
* @see SocksV4CmdRequestDecoder
|
* @see Socks4CmdRequestDecoder
|
||||||
*/
|
*/
|
||||||
public final class UnknownSocksV4Request extends SocksV4Request {
|
public final class UnknownSocks4Request extends Socks4Request {
|
||||||
|
|
||||||
public UnknownSocksV4Request() {
|
public static final UnknownSocks4Request INSTANCE = new UnknownSocks4Request();
|
||||||
}
|
|
||||||
|
private UnknownSocks4Request() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class UnknownSocksV4RequestHolder {
|
|
||||||
public static final UnknownSocksV4Request HOLDER_INSTANCE = new UnknownSocksV4Request();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnknownSocksV4Request getInstance() {
|
|
||||||
return UnknownSocksV4RequestHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -20,23 +20,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
/**
|
/**
|
||||||
* An unknown socks response.
|
* An unknown socks response.
|
||||||
*
|
*
|
||||||
* @see SocksV4CmdResponseDecoder
|
* @see Socks4CmdResponseDecoder
|
||||||
*/
|
*/
|
||||||
public final class UnknownSocksV4Response extends SocksV4Response {
|
public final class UnknownSocks4Response extends Socks4Response {
|
||||||
|
|
||||||
public UnknownSocksV4Response() {
|
public static final UnknownSocks4Response INSTANCE = new UnknownSocks4Response();
|
||||||
}
|
|
||||||
|
private UnknownSocks4Response() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class UnknownSocksV4ResponseHolder {
|
|
||||||
public static final UnknownSocksV4Response HOLDER_INSTANCE = new UnknownSocksV4Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnknownSocksV4Response getInstance() {
|
|
||||||
return UnknownSocksV4ResponseHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -15,6 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoder, decoder and their related message types for Socks.
|
* Encoder, decoder and their related message types for SOCKSv4 protocol.
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5AddressType {
|
public enum Socks5AddressType {
|
||||||
IPv4((byte) 0x01),
|
IPv4((byte) 0x01),
|
||||||
DOMAIN((byte) 0x03),
|
DOMAIN((byte) 0x03),
|
||||||
IPv6((byte) 0x04),
|
IPv6((byte) 0x04),
|
||||||
@ -24,12 +24,12 @@ public enum SocksV5AddressType {
|
|||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5AddressType(byte b) {
|
Socks5AddressType(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5AddressType valueOf(byte b) {
|
public static Socks5AddressType valueOf(byte b) {
|
||||||
for (SocksV5AddressType code : values()) {
|
for (Socks5AddressType code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -23,18 +23,18 @@ import java.nio.charset.CharsetEncoder;
|
|||||||
/**
|
/**
|
||||||
* An socks auth request.
|
* An socks auth request.
|
||||||
*
|
*
|
||||||
* @see SocksV5AuthResponse
|
* @see Socks5AuthResponse
|
||||||
* @see SocksV5AuthRequestDecoder
|
* @see Socks5AuthRequestDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5AuthRequest extends SocksV5Request {
|
public final class Socks5AuthRequest extends Socks5Request {
|
||||||
private static final CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII);
|
private static final CharsetEncoder asciiEncoder = CharsetUtil.getEncoder(CharsetUtil.US_ASCII);
|
||||||
private static final SocksV5SubnegotiationVersion SUBNEGOTIATION_VERSION =
|
private static final Socks5SubnegotiationVersion SUBNEGOTIATION_VERSION =
|
||||||
SocksV5SubnegotiationVersion.AUTH_PASSWORD;
|
Socks5SubnegotiationVersion.AUTH_PASSWORD;
|
||||||
private final String username;
|
private final String username;
|
||||||
private final String password;
|
private final String password;
|
||||||
|
|
||||||
public SocksV5AuthRequest(String username, String password) {
|
public Socks5AuthRequest(String username, String password) {
|
||||||
super(SocksV5RequestType.AUTH);
|
super(Socks5RequestType.AUTH);
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
throw new NullPointerException("username");
|
throw new NullPointerException("username");
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ public final class SocksV5AuthRequest extends SocksV5Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
|
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
|
||||||
byteBuf.writeByte(username.length());
|
byteBuf.writeByte(username.length());
|
||||||
byteBuf.writeBytes(username.getBytes(CharsetUtil.US_ASCII));
|
byteBuf.writeBytes(username.getBytes(CharsetUtil.US_ASCII));
|
@ -18,23 +18,23 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AuthRequestDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5AuthRequestDecoder.State;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5AuthRequest}.
|
* Decodes {@link ByteBuf}s into {@link Socks5AuthRequest}.
|
||||||
* Before returning SocksRequest decoder removes itself from pipeline.
|
* Before returning SocksRequest decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> {
|
public class Socks5AuthRequestDecoder extends ReplayingDecoder<State> {
|
||||||
private SocksV5SubnegotiationVersion version;
|
private Socks5SubnegotiationVersion version;
|
||||||
private int fieldLength;
|
private int fieldLength;
|
||||||
private String username;
|
private String username;
|
||||||
private String password;
|
private String password;
|
||||||
private SocksV5Request msg = UnknownSocksV5Request.getInstance();
|
private Socks5Request msg = UnknownSocks5Request.INSTANCE;
|
||||||
|
|
||||||
public SocksV5AuthRequestDecoder() {
|
public Socks5AuthRequestDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf, List<Object> out) throws Exception {
|
||||||
switch (state()) {
|
switch (state()) {
|
||||||
case CHECK_PROTOCOL_VERSION: {
|
case CHECK_PROTOCOL_VERSION: {
|
||||||
version = SocksV5SubnegotiationVersion.valueOf(byteBuf.readByte());
|
version = Socks5SubnegotiationVersion.valueOf(byteBuf.readByte());
|
||||||
if (version != SocksV5SubnegotiationVersion.AUTH_PASSWORD) {
|
if (version != Socks5SubnegotiationVersion.AUTH_PASSWORD) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
checkpoint(State.READ_USERNAME);
|
checkpoint(State.READ_USERNAME);
|
||||||
@ -56,7 +56,7 @@ public class SocksV5AuthRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
case READ_PASSWORD: {
|
case READ_PASSWORD: {
|
||||||
fieldLength = byteBuf.readByte();
|
fieldLength = byteBuf.readByte();
|
||||||
password = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
password = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
||||||
msg = new SocksV5AuthRequest(username, password);
|
msg = new Socks5AuthRequest(username, password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.pipeline().remove(this);
|
ctx.pipeline().remove(this);
|
@ -20,16 +20,16 @@ import io.netty.buffer.ByteBuf;
|
|||||||
/**
|
/**
|
||||||
* An socks auth response.
|
* An socks auth response.
|
||||||
*
|
*
|
||||||
* @see SocksV5AuthRequest
|
* @see Socks5AuthRequest
|
||||||
* @see SocksV5AuthResponseDecoder
|
* @see Socks5AuthResponseDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5AuthResponse extends SocksV5Response {
|
public final class Socks5AuthResponse extends Socks5Response {
|
||||||
private static final SocksV5SubnegotiationVersion SUBNEGOTIATION_VERSION =
|
private static final Socks5SubnegotiationVersion SUBNEGOTIATION_VERSION =
|
||||||
SocksV5SubnegotiationVersion.AUTH_PASSWORD;
|
Socks5SubnegotiationVersion.AUTH_PASSWORD;
|
||||||
private final SocksV5AuthStatus authStatus;
|
private final Socks5AuthStatus authStatus;
|
||||||
|
|
||||||
public SocksV5AuthResponse(SocksV5AuthStatus authStatus) {
|
public Socks5AuthResponse(Socks5AuthStatus authStatus) {
|
||||||
super(SocksV5ResponseType.AUTH);
|
super(Socks5ResponseType.AUTH);
|
||||||
if (authStatus == null) {
|
if (authStatus == null) {
|
||||||
throw new NullPointerException("authStatus");
|
throw new NullPointerException("authStatus");
|
||||||
}
|
}
|
||||||
@ -37,16 +37,16 @@ public final class SocksV5AuthResponse extends SocksV5Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5AuthStatus} of this {@link SocksV5AuthResponse}
|
* Returns the {@link Socks5AuthStatus} of this {@link Socks5AuthResponse}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5AuthStatus} of this {@link SocksV5AuthResponse}
|
* @return The {@link Socks5AuthStatus} of this {@link Socks5AuthResponse}
|
||||||
*/
|
*/
|
||||||
public SocksV5AuthStatus authStatus() {
|
public Socks5AuthStatus authStatus() {
|
||||||
return authStatus;
|
return authStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
|
byteBuf.writeByte(SUBNEGOTIATION_VERSION.byteValue());
|
||||||
byteBuf.writeByte(authStatus.byteValue());
|
byteBuf.writeByte(authStatus.byteValue());
|
||||||
}
|
}
|
@ -18,20 +18,20 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AuthResponseDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5AuthResponseDecoder.State;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5AuthResponse}.
|
* Decodes {@link ByteBuf}s into {@link Socks5AuthResponse}.
|
||||||
* Before returning SocksResponse decoder removes itself from pipeline.
|
* Before returning SocksResponse decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5AuthResponseDecoder extends ReplayingDecoder<State> {
|
public class Socks5AuthResponseDecoder extends ReplayingDecoder<State> {
|
||||||
private SocksV5SubnegotiationVersion version;
|
private Socks5SubnegotiationVersion version;
|
||||||
private SocksV5AuthStatus authStatus;
|
private Socks5AuthStatus authStatus;
|
||||||
private SocksV5Response msg = UnknownSocksV5Response.getInstance();
|
private Socks5Response msg = UnknownSocks5Response.INSTANCE;
|
||||||
|
|
||||||
public SocksV5AuthResponseDecoder() {
|
public Socks5AuthResponseDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,15 +40,15 @@ public class SocksV5AuthResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
switch (state()) {
|
switch (state()) {
|
||||||
case CHECK_PROTOCOL_VERSION: {
|
case CHECK_PROTOCOL_VERSION: {
|
||||||
version = SocksV5SubnegotiationVersion.valueOf(byteBuf.readByte());
|
version = Socks5SubnegotiationVersion.valueOf(byteBuf.readByte());
|
||||||
if (version != SocksV5SubnegotiationVersion.AUTH_PASSWORD) {
|
if (version != Socks5SubnegotiationVersion.AUTH_PASSWORD) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
checkpoint(State.READ_AUTH_RESPONSE);
|
checkpoint(State.READ_AUTH_RESPONSE);
|
||||||
}
|
}
|
||||||
case READ_AUTH_RESPONSE: {
|
case READ_AUTH_RESPONSE: {
|
||||||
authStatus = SocksV5AuthStatus.valueOf(byteBuf.readByte());
|
authStatus = Socks5AuthStatus.valueOf(byteBuf.readByte());
|
||||||
msg = new SocksV5AuthResponse(authStatus);
|
msg = new Socks5AuthResponse(authStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
channelHandlerContext.pipeline().remove(this);
|
channelHandlerContext.pipeline().remove(this);
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5AuthScheme {
|
public enum Socks5AuthScheme {
|
||||||
NO_AUTH((byte) 0x00),
|
NO_AUTH((byte) 0x00),
|
||||||
AUTH_GSSAPI((byte) 0x01),
|
AUTH_GSSAPI((byte) 0x01),
|
||||||
AUTH_PASSWORD((byte) 0x02),
|
AUTH_PASSWORD((byte) 0x02),
|
||||||
@ -24,12 +24,12 @@ public enum SocksV5AuthScheme {
|
|||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5AuthScheme(byte b) {
|
Socks5AuthScheme(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5AuthScheme valueOf(byte b) {
|
public static Socks5AuthScheme valueOf(byte b) {
|
||||||
for (SocksV5AuthScheme code : values()) {
|
for (Socks5AuthScheme code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5AuthStatus {
|
public enum Socks5AuthStatus {
|
||||||
SUCCESS((byte) 0x00),
|
SUCCESS((byte) 0x00),
|
||||||
FAILURE((byte) 0xff);
|
FAILURE((byte) 0xff);
|
||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5AuthStatus(byte b) {
|
Socks5AuthStatus(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5AuthStatus valueOf(byte b) {
|
public static Socks5AuthStatus valueOf(byte b) {
|
||||||
for (SocksV5AuthStatus code : values()) {
|
for (Socks5AuthStatus code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -24,17 +24,17 @@ import java.net.IDN;
|
|||||||
/**
|
/**
|
||||||
* An socks cmd request.
|
* An socks cmd request.
|
||||||
*
|
*
|
||||||
* @see SocksV5CmdResponse
|
* @see Socks5CmdResponse
|
||||||
* @see SocksV5CmdRequestDecoder
|
* @see Socks5CmdRequestDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5CmdRequest extends SocksV5Request {
|
public final class Socks5CmdRequest extends Socks5Request {
|
||||||
private final SocksV5CmdType cmdType;
|
private final Socks5CmdType cmdType;
|
||||||
private final SocksV5AddressType addressType;
|
private final Socks5AddressType addressType;
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
public SocksV5CmdRequest(SocksV5CmdType cmdType, SocksV5AddressType addressType, String host, int port) {
|
public Socks5CmdRequest(Socks5CmdType cmdType, Socks5AddressType addressType, String host, int port) {
|
||||||
super(SocksV5RequestType.CMD);
|
super(Socks5RequestType.CMD);
|
||||||
if (cmdType == null) {
|
if (cmdType == null) {
|
||||||
throw new NullPointerException("cmdType");
|
throw new NullPointerException("cmdType");
|
||||||
}
|
}
|
||||||
@ -73,43 +73,43 @@ public final class SocksV5CmdRequest extends SocksV5Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5CmdType} of this {@link SocksV5CmdRequest}
|
* Returns the {@link Socks5CmdType} of this {@link Socks5CmdRequest}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5CmdType} of this {@link SocksV5CmdRequest}
|
* @return The {@link Socks5CmdType} of this {@link Socks5CmdRequest}
|
||||||
*/
|
*/
|
||||||
public SocksV5CmdType cmdType() {
|
public Socks5CmdType cmdType() {
|
||||||
return cmdType;
|
return cmdType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5AddressType} of this {@link SocksV5CmdRequest}
|
* Returns the {@link Socks5AddressType} of this {@link Socks5CmdRequest}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5AddressType} of this {@link SocksV5CmdRequest}
|
* @return The {@link Socks5AddressType} of this {@link Socks5CmdRequest}
|
||||||
*/
|
*/
|
||||||
public SocksV5AddressType addressType() {
|
public Socks5AddressType addressType() {
|
||||||
return addressType;
|
return addressType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns host that is used as a parameter in {@link SocksV5CmdType}
|
* Returns host that is used as a parameter in {@link Socks5CmdType}
|
||||||
*
|
*
|
||||||
* @return host that is used as a parameter in {@link SocksV5CmdType}
|
* @return host that is used as a parameter in {@link Socks5CmdType}
|
||||||
*/
|
*/
|
||||||
public String host() {
|
public String host() {
|
||||||
return IDN.toUnicode(host);
|
return IDN.toUnicode(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns port that is used as a parameter in {@link SocksV5CmdType}
|
* Returns port that is used as a parameter in {@link Socks5CmdType}
|
||||||
*
|
*
|
||||||
* @return port that is used as a parameter in {@link SocksV5CmdType}
|
* @return port that is used as a parameter in {@link Socks5CmdType}
|
||||||
*/
|
*/
|
||||||
public int port() {
|
public int port() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(protocolVersion().byteValue());
|
byteBuf.writeByte(protocolVersion().byteValue());
|
||||||
byteBuf.writeByte(cmdType.byteValue());
|
byteBuf.writeByte(cmdType.byteValue());
|
||||||
byteBuf.writeByte(0x00);
|
byteBuf.writeByte(0x00);
|
@ -19,27 +19,27 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequestDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdRequestDecoder.State;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5CmdRequest}.
|
* Decodes {@link ByteBuf}s into {@link Socks5CmdRequest}.
|
||||||
* Before returning SocksRequest decoder removes itself from pipeline.
|
* Before returning SocksRequest decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5CmdRequestDecoder extends ReplayingDecoder<State> {
|
public class Socks5CmdRequestDecoder extends ReplayingDecoder<State> {
|
||||||
private SocksProtocolVersion version;
|
private SocksProtocolVersion version;
|
||||||
private int fieldLength;
|
private int fieldLength;
|
||||||
private SocksV5CmdType cmdType;
|
private Socks5CmdType cmdType;
|
||||||
private SocksV5AddressType addressType;
|
private Socks5AddressType addressType;
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
private byte reserved;
|
private byte reserved;
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
private SocksV5Request msg = UnknownSocksV5Request.getInstance();
|
private Socks5Request msg = UnknownSocks5Request.INSTANCE;
|
||||||
|
|
||||||
public SocksV5CmdRequestDecoder() {
|
public Socks5CmdRequestDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,30 +54,30 @@ public class SocksV5CmdRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
checkpoint(State.READ_CMD_HEADER);
|
checkpoint(State.READ_CMD_HEADER);
|
||||||
}
|
}
|
||||||
case READ_CMD_HEADER: {
|
case READ_CMD_HEADER: {
|
||||||
cmdType = SocksV5CmdType.valueOf(byteBuf.readByte());
|
cmdType = Socks5CmdType.valueOf(byteBuf.readByte());
|
||||||
reserved = byteBuf.readByte();
|
reserved = byteBuf.readByte();
|
||||||
addressType = SocksV5AddressType.valueOf(byteBuf.readByte());
|
addressType = Socks5AddressType.valueOf(byteBuf.readByte());
|
||||||
checkpoint(State.READ_CMD_ADDRESS);
|
checkpoint(State.READ_CMD_ADDRESS);
|
||||||
}
|
}
|
||||||
case READ_CMD_ADDRESS: {
|
case READ_CMD_ADDRESS: {
|
||||||
switch (addressType) {
|
switch (addressType) {
|
||||||
case IPv4: {
|
case IPv4: {
|
||||||
host = SocksV5CommonUtils.intToIp(byteBuf.readInt());
|
host = Socks5CommonUtils.intToIp(byteBuf.readInt());
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdRequest(cmdType, addressType, host, port);
|
msg = new Socks5CmdRequest(cmdType, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DOMAIN: {
|
case DOMAIN: {
|
||||||
fieldLength = byteBuf.readByte();
|
fieldLength = byteBuf.readByte();
|
||||||
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdRequest(cmdType, addressType, host, port);
|
msg = new Socks5CmdRequest(cmdType, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IPv6: {
|
case IPv6: {
|
||||||
host = SocksV5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
|
host = Socks5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdRequest(cmdType, addressType, host, port);
|
msg = new Socks5CmdRequest(cmdType, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
@ -24,13 +24,13 @@ import java.net.IDN;
|
|||||||
/**
|
/**
|
||||||
* A socks cmd response.
|
* A socks cmd response.
|
||||||
*
|
*
|
||||||
* @see SocksV5CmdRequest
|
* @see Socks5CmdRequest
|
||||||
* @see SocksV5CmdResponseDecoder
|
* @see Socks5CmdResponseDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5CmdResponse extends SocksV5Response {
|
public final class Socks5CmdResponse extends Socks5Response {
|
||||||
private final SocksV5CmdStatus cmdStatus;
|
private final Socks5CmdStatus cmdStatus;
|
||||||
|
|
||||||
private final SocksV5AddressType addressType;
|
private final Socks5AddressType addressType;
|
||||||
private final String host;
|
private final String host;
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ public final class SocksV5CmdResponse extends SocksV5Response {
|
|||||||
0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00};
|
0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
public SocksV5CmdResponse(SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType) {
|
public Socks5CmdResponse(Socks5CmdStatus cmdStatus, Socks5AddressType addressType) {
|
||||||
this(cmdStatus, addressType, null, 0);
|
this(cmdStatus, addressType, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +59,8 @@ public final class SocksV5CmdResponse extends SocksV5Response {
|
|||||||
* @throws IllegalArgumentException in case host or port cannot be validated
|
* @throws IllegalArgumentException in case host or port cannot be validated
|
||||||
* @see IDN#toASCII(String)
|
* @see IDN#toASCII(String)
|
||||||
*/
|
*/
|
||||||
public SocksV5CmdResponse(SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType, String host, int port) {
|
public Socks5CmdResponse(Socks5CmdStatus cmdStatus, Socks5AddressType addressType, String host, int port) {
|
||||||
super(SocksV5ResponseType.CMD);
|
super(Socks5ResponseType.CMD);
|
||||||
if (cmdStatus == null) {
|
if (cmdStatus == null) {
|
||||||
throw new NullPointerException("cmdStatus");
|
throw new NullPointerException("cmdStatus");
|
||||||
}
|
}
|
||||||
@ -100,29 +100,29 @@ public final class SocksV5CmdResponse extends SocksV5Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5CmdStatus} of this {@link SocksV5CmdResponse}
|
* Returns the {@link Socks5CmdStatus} of this {@link Socks5CmdResponse}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5CmdStatus} of this {@link SocksV5CmdResponse}
|
* @return The {@link Socks5CmdStatus} of this {@link Socks5CmdResponse}
|
||||||
*/
|
*/
|
||||||
public SocksV5CmdStatus cmdStatus() {
|
public Socks5CmdStatus cmdStatus() {
|
||||||
return cmdStatus;
|
return cmdStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5AddressType} of this {@link SocksV5CmdResponse}
|
* Returns the {@link Socks5AddressType} of this {@link Socks5CmdResponse}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5AddressType} of this {@link SocksV5CmdResponse}
|
* @return The {@link Socks5AddressType} of this {@link Socks5CmdResponse}
|
||||||
*/
|
*/
|
||||||
public SocksV5AddressType addressType() {
|
public Socks5AddressType addressType() {
|
||||||
return addressType;
|
return addressType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns host that is used as a parameter in {@link SocksV5CmdType}.
|
* Returns host that is used as a parameter in {@link Socks5CmdType}.
|
||||||
* Host (BND.ADDR field in response) is address that server used when connecting to the target host.
|
* Host (BND.ADDR field in response) is address that server used when connecting to the target host.
|
||||||
* This is typically different from address which client uses to connect to the SOCKS server.
|
* This is typically different from address which client uses to connect to the SOCKS server.
|
||||||
*
|
*
|
||||||
* @return host that is used as a parameter in {@link SocksV5CmdType}
|
* @return host that is used as a parameter in {@link Socks5CmdType}
|
||||||
* or null when there was no host specified during response construction
|
* or null when there was no host specified during response construction
|
||||||
*/
|
*/
|
||||||
public String host() {
|
public String host() {
|
||||||
@ -134,17 +134,17 @@ public final class SocksV5CmdResponse extends SocksV5Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns port that is used as a parameter in {@link SocksV5CmdType}.
|
* Returns port that is used as a parameter in {@link Socks5CmdType}.
|
||||||
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
|
* Port (BND.PORT field in response) is port that the server assigned to connect to the target host.
|
||||||
*
|
*
|
||||||
* @return port that is used as a parameter in {@link SocksV5CmdType}
|
* @return port that is used as a parameter in {@link Socks5CmdType}
|
||||||
*/
|
*/
|
||||||
public int port() {
|
public int port() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(protocolVersion().byteValue());
|
byteBuf.writeByte(protocolVersion().byteValue());
|
||||||
byteBuf.writeByte(cmdStatus.byteValue());
|
byteBuf.writeByte(cmdStatus.byteValue());
|
||||||
byteBuf.writeByte(0x00);
|
byteBuf.writeByte(0x00);
|
@ -19,26 +19,25 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdResponseDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdResponseDecoder.State;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5CmdResponse}.
|
* Decodes {@link ByteBuf}s into {@link Socks5CmdResponse}.
|
||||||
* Before returning SocksResponse decoder removes itself from pipeline.
|
* Before returning SocksResponse decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5CmdResponseDecoder extends ReplayingDecoder<State> {
|
public class Socks5CmdResponseDecoder extends ReplayingDecoder<State> {
|
||||||
private SocksProtocolVersion version;
|
private SocksProtocolVersion version;
|
||||||
private int fieldLength;
|
private int fieldLength;
|
||||||
private SocksV5CmdStatus cmdStatus;
|
private Socks5CmdStatus cmdStatus;
|
||||||
private SocksV5AddressType addressType;
|
private Socks5AddressType addressType;
|
||||||
private byte reserved;
|
|
||||||
private String host;
|
private String host;
|
||||||
private int port;
|
private int port;
|
||||||
private SocksV5Response msg = UnknownSocksV5Response.getInstance();
|
private Socks5Response msg = UnknownSocks5Response.INSTANCE;
|
||||||
|
|
||||||
public SocksV5CmdResponseDecoder() {
|
public Socks5CmdResponseDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,30 +52,30 @@ public class SocksV5CmdResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
checkpoint(State.READ_CMD_HEADER);
|
checkpoint(State.READ_CMD_HEADER);
|
||||||
}
|
}
|
||||||
case READ_CMD_HEADER: {
|
case READ_CMD_HEADER: {
|
||||||
cmdStatus = SocksV5CmdStatus.valueOf(byteBuf.readByte());
|
cmdStatus = Socks5CmdStatus.valueOf(byteBuf.readByte());
|
||||||
reserved = byteBuf.readByte();
|
byteBuf.skipBytes(1); // reserved
|
||||||
addressType = SocksV5AddressType.valueOf(byteBuf.readByte());
|
addressType = Socks5AddressType.valueOf(byteBuf.readByte());
|
||||||
checkpoint(State.READ_CMD_ADDRESS);
|
checkpoint(State.READ_CMD_ADDRESS);
|
||||||
}
|
}
|
||||||
case READ_CMD_ADDRESS: {
|
case READ_CMD_ADDRESS: {
|
||||||
switch (addressType) {
|
switch (addressType) {
|
||||||
case IPv4: {
|
case IPv4: {
|
||||||
host = SocksV5CommonUtils.intToIp(byteBuf.readInt());
|
host = Socks5CommonUtils.intToIp(byteBuf.readInt());
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port);
|
msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DOMAIN: {
|
case DOMAIN: {
|
||||||
fieldLength = byteBuf.readByte();
|
fieldLength = byteBuf.readByte();
|
||||||
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
host = byteBuf.readBytes(fieldLength).toString(CharsetUtil.US_ASCII);
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port);
|
msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IPv6: {
|
case IPv6: {
|
||||||
host = SocksV5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
|
host = Socks5CommonUtils.ipv6toStr(byteBuf.readBytes(16).array());
|
||||||
port = byteBuf.readUnsignedShort();
|
port = byteBuf.readUnsignedShort();
|
||||||
msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port);
|
msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5CmdStatus {
|
public enum Socks5CmdStatus {
|
||||||
SUCCESS((byte) 0x00),
|
SUCCESS((byte) 0x00),
|
||||||
FAILURE((byte) 0x01),
|
FAILURE((byte) 0x01),
|
||||||
FORBIDDEN((byte) 0x02),
|
FORBIDDEN((byte) 0x02),
|
||||||
@ -30,12 +30,12 @@ public enum SocksV5CmdStatus {
|
|||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5CmdStatus(byte b) {
|
Socks5CmdStatus(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5CmdStatus valueOf(byte b) {
|
public static Socks5CmdStatus valueOf(byte b) {
|
||||||
for (SocksV5CmdStatus code : values()) {
|
for (Socks5CmdStatus code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5CmdType {
|
public enum Socks5CmdType {
|
||||||
CONNECT((byte) 0x01),
|
CONNECT((byte) 0x01),
|
||||||
BIND((byte) 0x02),
|
BIND((byte) 0x02),
|
||||||
UDP((byte) 0x03),
|
UDP((byte) 0x03),
|
||||||
@ -24,12 +24,12 @@ public enum SocksV5CmdType {
|
|||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5CmdType(byte b) {
|
Socks5CmdType(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5CmdType valueOf(byte b) {
|
public static Socks5CmdType valueOf(byte b) {
|
||||||
for (SocksV5CmdType code : values()) {
|
for (Socks5CmdType code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -16,7 +16,8 @@
|
|||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
public final class SocksV5CommonUtils {
|
final class Socks5CommonUtils {
|
||||||
|
|
||||||
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
|
private static final int SECOND_ADDRESS_OCTET_SHIFT = 16;
|
||||||
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
|
private static final int FIRST_ADDRESS_OCTET_SHIFT = 24;
|
||||||
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
|
private static final int THIRD_ADDRESS_OCTET_SHIFT = 8;
|
||||||
@ -25,7 +26,7 @@ public final class SocksV5CommonUtils {
|
|||||||
/**
|
/**
|
||||||
* A constructor to stop this class being constructed.
|
* A constructor to stop this class being constructed.
|
||||||
*/
|
*/
|
||||||
private SocksV5CommonUtils() {
|
private Socks5CommonUtils() {
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
@ -23,14 +23,14 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* An socks init request.
|
* An socks init request.
|
||||||
*
|
*
|
||||||
* @see SocksV5InitResponse
|
* @see Socks5InitResponse
|
||||||
* @see SocksV5InitRequestDecoder
|
* @see Socks5InitRequestDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5InitRequest extends SocksV5Request {
|
public final class Socks5InitRequest extends Socks5Request {
|
||||||
private final List<SocksV5AuthScheme> authSchemes;
|
private final List<Socks5AuthScheme> authSchemes;
|
||||||
|
|
||||||
public SocksV5InitRequest(List<SocksV5AuthScheme> authSchemes) {
|
public Socks5InitRequest(List<Socks5AuthScheme> authSchemes) {
|
||||||
super(SocksV5RequestType.INIT);
|
super(Socks5RequestType.INIT);
|
||||||
if (authSchemes == null) {
|
if (authSchemes == null) {
|
||||||
throw new NullPointerException("authSchemes");
|
throw new NullPointerException("authSchemes");
|
||||||
}
|
}
|
||||||
@ -38,19 +38,19 @@ public final class SocksV5InitRequest extends SocksV5Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the List<{@link SocksV5AuthScheme}> of this {@link SocksV5InitRequest}
|
* Returns the List<{@link Socks5AuthScheme}> of this {@link Socks5InitRequest}
|
||||||
*
|
*
|
||||||
* @return The List<{@link SocksV5AuthScheme}> of this {@link SocksV5InitRequest}
|
* @return The List<{@link Socks5AuthScheme}> of this {@link Socks5InitRequest}
|
||||||
*/
|
*/
|
||||||
public List<SocksV5AuthScheme> authSchemes() {
|
public List<Socks5AuthScheme> authSchemes() {
|
||||||
return Collections.unmodifiableList(authSchemes);
|
return Collections.unmodifiableList(authSchemes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(protocolVersion().byteValue());
|
byteBuf.writeByte(protocolVersion().byteValue());
|
||||||
byteBuf.writeByte(authSchemes.size());
|
byteBuf.writeByte(authSchemes.size());
|
||||||
for (SocksV5AuthScheme authScheme : authSchemes) {
|
for (Socks5AuthScheme authScheme : authSchemes) {
|
||||||
byteBuf.writeByte(authScheme.byteValue());
|
byteBuf.writeByte(authScheme.byteValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,22 +19,22 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5InitRequestDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5InitRequestDecoder.State;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5InitRequest}.
|
* Decodes {@link ByteBuf}s into {@link Socks5InitRequest}.
|
||||||
* Before returning SocksRequest decoder removes itself from pipeline.
|
* Before returning SocksRequest decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5InitRequestDecoder extends ReplayingDecoder<State> {
|
public class Socks5InitRequestDecoder extends ReplayingDecoder<State> {
|
||||||
private final List<SocksV5AuthScheme> authSchemes = new ArrayList<SocksV5AuthScheme>();
|
private final List<Socks5AuthScheme> authSchemes = new ArrayList<Socks5AuthScheme>();
|
||||||
private SocksProtocolVersion version;
|
private SocksProtocolVersion version;
|
||||||
private byte authSchemeNum;
|
private byte authSchemeNum;
|
||||||
private SocksV5Request msg = UnknownSocksV5Request.getInstance();
|
private Socks5Request msg = UnknownSocks5Request.INSTANCE;
|
||||||
|
|
||||||
public SocksV5InitRequestDecoder() {
|
public Socks5InitRequestDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,9 +52,9 @@ public class SocksV5InitRequestDecoder extends ReplayingDecoder<State> {
|
|||||||
authSchemes.clear();
|
authSchemes.clear();
|
||||||
authSchemeNum = byteBuf.readByte();
|
authSchemeNum = byteBuf.readByte();
|
||||||
for (int i = 0; i < authSchemeNum; i++) {
|
for (int i = 0; i < authSchemeNum; i++) {
|
||||||
authSchemes.add(SocksV5AuthScheme.valueOf(byteBuf.readByte()));
|
authSchemes.add(Socks5AuthScheme.valueOf(byteBuf.readByte()));
|
||||||
}
|
}
|
||||||
msg = new SocksV5InitRequest(authSchemes);
|
msg = new Socks5InitRequest(authSchemes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,14 +20,14 @@ import io.netty.buffer.ByteBuf;
|
|||||||
/**
|
/**
|
||||||
* An socks init response.
|
* An socks init response.
|
||||||
*
|
*
|
||||||
* @see SocksV5InitRequest
|
* @see Socks5InitRequest
|
||||||
* @see SocksV5InitResponseDecoder
|
* @see Socks5InitResponseDecoder
|
||||||
*/
|
*/
|
||||||
public final class SocksV5InitResponse extends SocksV5Response {
|
public final class Socks5InitResponse extends Socks5Response {
|
||||||
private final SocksV5AuthScheme authScheme;
|
private final Socks5AuthScheme authScheme;
|
||||||
|
|
||||||
public SocksV5InitResponse(SocksV5AuthScheme authScheme) {
|
public Socks5InitResponse(Socks5AuthScheme authScheme) {
|
||||||
super(SocksV5ResponseType.INIT);
|
super(Socks5ResponseType.INIT);
|
||||||
if (authScheme == null) {
|
if (authScheme == null) {
|
||||||
throw new NullPointerException("authScheme");
|
throw new NullPointerException("authScheme");
|
||||||
}
|
}
|
||||||
@ -35,16 +35,16 @@ public final class SocksV5InitResponse extends SocksV5Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link SocksV5AuthScheme} of this {@link SocksV5InitResponse}
|
* Returns the {@link Socks5AuthScheme} of this {@link Socks5InitResponse}
|
||||||
*
|
*
|
||||||
* @return The {@link SocksV5AuthScheme} of this {@link SocksV5InitResponse}
|
* @return The {@link Socks5AuthScheme} of this {@link Socks5InitResponse}
|
||||||
*/
|
*/
|
||||||
public SocksV5AuthScheme authScheme() {
|
public Socks5AuthScheme authScheme() {
|
||||||
return authScheme;
|
return authScheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
byteBuf.writeByte(protocolVersion().byteValue());
|
byteBuf.writeByte(protocolVersion().byteValue());
|
||||||
byteBuf.writeByte(authScheme.byteValue());
|
byteBuf.writeByte(authScheme.byteValue());
|
||||||
}
|
}
|
@ -19,21 +19,21 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.ReplayingDecoder;
|
import io.netty.handler.codec.ReplayingDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5InitResponseDecoder.State;
|
import io.netty.handler.codec.socksx.v5.Socks5InitResponseDecoder.State;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes {@link ByteBuf}s into {@link SocksV5InitResponse}.
|
* Decodes {@link ByteBuf}s into {@link Socks5InitResponse}.
|
||||||
* Before returning SocksResponse decoder removes itself from pipeline.
|
* Before returning SocksResponse decoder removes itself from pipeline.
|
||||||
*/
|
*/
|
||||||
public class SocksV5InitResponseDecoder extends ReplayingDecoder<State> {
|
public class Socks5InitResponseDecoder extends ReplayingDecoder<State> {
|
||||||
private SocksProtocolVersion version;
|
private SocksProtocolVersion version;
|
||||||
private SocksV5AuthScheme authScheme;
|
private Socks5AuthScheme authScheme;
|
||||||
|
|
||||||
private SocksV5Response msg = UnknownSocksV5Response.getInstance();
|
private Socks5Response msg = UnknownSocks5Response.INSTANCE;
|
||||||
|
|
||||||
public SocksV5InitResponseDecoder() {
|
public Socks5InitResponseDecoder() {
|
||||||
super(State.CHECK_PROTOCOL_VERSION);
|
super(State.CHECK_PROTOCOL_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +48,8 @@ public class SocksV5InitResponseDecoder extends ReplayingDecoder<State> {
|
|||||||
checkpoint(State.READ_PREFFERED_AUTH_TYPE);
|
checkpoint(State.READ_PREFFERED_AUTH_TYPE);
|
||||||
}
|
}
|
||||||
case READ_PREFFERED_AUTH_TYPE: {
|
case READ_PREFFERED_AUTH_TYPE: {
|
||||||
authScheme = SocksV5AuthScheme.valueOf(byteBuf.readByte());
|
authScheme = Socks5AuthScheme.valueOf(byteBuf.readByte());
|
||||||
msg = new SocksV5InitResponse(authScheme);
|
msg = new Socks5InitResponse(authScheme);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,40 +13,40 @@
|
|||||||
* License for the specific language governing permissions and limitations
|
* License for the specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToByteEncoder;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
||||||
|
import io.netty.handler.codec.socksx.SocksMessage;
|
||||||
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes an {@link SocksMessage} into a {@link ByteBuf}.
|
* Encodes a {@link Socks5Request} and {@link Socks5Response} into a {@link ByteBuf}.
|
||||||
* {@link MessageToByteEncoder} implementation.
|
|
||||||
* Use this with {@link SocksV4CmdRequest},
|
|
||||||
* {@link SocksV4CmdRequest},
|
|
||||||
* {@link SocksV5InitRequest},
|
|
||||||
* {@link SocksV5InitResponse},
|
|
||||||
* {@link SocksV5AuthRequest},
|
|
||||||
* {@link SocksV5AuthResponse},
|
|
||||||
* {@link SocksV5CmdRequest} and
|
|
||||||
* {@link SocksV5CmdResponse}
|
|
||||||
*/
|
*/
|
||||||
@ChannelHandler.Sharable
|
@ChannelHandler.Sharable
|
||||||
public class SocksMessageEncoder extends MessageToByteEncoder<SocksMessage> {
|
public final class Socks5MessageEncoder extends MessageToByteEncoder<SocksMessage> {
|
||||||
private static final String name = "SOCKS_MESSAGE_ENCODER";
|
|
||||||
|
public static final Socks5MessageEncoder INSTANCE = new Socks5MessageEncoder();
|
||||||
|
|
||||||
|
private Socks5MessageEncoder() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptOutboundMessage(Object msg) throws Exception {
|
||||||
|
return super.acceptOutboundMessage(msg) &&
|
||||||
|
((SocksMessage) msg).protocolVersion() == SocksProtocolVersion.SOCKS5;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception {
|
protected void encode(ChannelHandlerContext ctx, SocksMessage msg, ByteBuf out) throws Exception {
|
||||||
msg.encodeAsByteBuf(out);
|
if (msg instanceof Socks5Response) {
|
||||||
}
|
((Socks5Response) msg).encodeAsByteBuf(out);
|
||||||
|
} else if (msg instanceof Socks5Request) {
|
||||||
private static class SocksMessageEncoderHolder {
|
((Socks5Request) msg).encodeAsByteBuf(out);
|
||||||
public static final SocksMessageEncoder HOLDER_INSTANCE = new SocksMessageEncoder();
|
} else {
|
||||||
}
|
// Should not reach here.
|
||||||
|
throw new Error();
|
||||||
public static SocksMessageEncoder getInstance() {
|
}
|
||||||
return SocksMessageEncoderHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -15,27 +15,27 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.socksx.SocksMessageType;
|
import io.netty.handler.codec.socks.SocksMessage;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.SocksRequest;
|
import io.netty.handler.codec.socksx.SocksRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksRequest, providing common properties for
|
* An abstract class that defines a SocksRequest, providing common properties for
|
||||||
* {@link SocksV5InitRequest},
|
* {@link Socks5InitRequest},
|
||||||
* {@link SocksV5AuthRequest},
|
* {@link Socks5AuthRequest},
|
||||||
* {@link SocksV5CmdRequest} and
|
* {@link Socks5CmdRequest} and
|
||||||
* {@link UnknownSocksV5Request}.
|
* {@link UnknownSocks5Request}.
|
||||||
*
|
*
|
||||||
* @see SocksV5InitRequest
|
* @see Socks5InitRequest
|
||||||
* @see SocksV5AuthRequest
|
* @see Socks5AuthRequest
|
||||||
* @see SocksV5CmdRequest
|
* @see Socks5CmdRequest
|
||||||
* @see UnknownSocksV5Request
|
* @see UnknownSocks5Request
|
||||||
*/
|
*/
|
||||||
public abstract class SocksV5Request extends SocksRequest {
|
public abstract class Socks5Request extends SocksRequest {
|
||||||
private final SocksV5RequestType requestType;
|
private final Socks5RequestType requestType;
|
||||||
|
|
||||||
protected SocksV5Request(SocksV5RequestType requestType) {
|
protected Socks5Request(Socks5RequestType requestType) {
|
||||||
super(SocksProtocolVersion.SOCKS5);
|
super(SocksProtocolVersion.SOCKS5);
|
||||||
if (requestType == null) {
|
if (requestType == null) {
|
||||||
throw new NullPointerException("requestType");
|
throw new NullPointerException("requestType");
|
||||||
@ -48,7 +48,13 @@ public abstract class SocksV5Request extends SocksRequest {
|
|||||||
*
|
*
|
||||||
* @return socks request type
|
* @return socks request type
|
||||||
*/
|
*/
|
||||||
public SocksV5RequestType requestType() {
|
public Socks5RequestType requestType() {
|
||||||
return requestType;
|
return requestType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
|
||||||
|
* because we do not want to expose this method to users.
|
||||||
|
*/
|
||||||
|
abstract void encodeAsByteBuf(ByteBuf byteBuf);
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
/**
|
/**
|
||||||
* Type of socks request
|
* Type of socks request
|
||||||
*/
|
*/
|
||||||
public enum SocksV5RequestType {
|
public enum Socks5RequestType {
|
||||||
INIT,
|
INIT,
|
||||||
AUTH,
|
AUTH,
|
||||||
CMD,
|
CMD,
|
@ -15,27 +15,27 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.handler.codec.socksx.SocksMessageType;
|
import io.netty.handler.codec.socks.SocksMessage;
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.SocksResponse;
|
import io.netty.handler.codec.socksx.SocksResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract class that defines a SocksResponse, providing common properties for
|
* An abstract class that defines a SocksResponse, providing common properties for
|
||||||
* {@link SocksV5InitResponse},
|
* {@link Socks5InitResponse},
|
||||||
* {@link SocksV5AuthResponse},
|
* {@link Socks5AuthResponse},
|
||||||
* {@link SocksV5CmdResponse}
|
* {@link Socks5CmdResponse}
|
||||||
* and {@link UnknownSocksV5Response}.
|
* and {@link UnknownSocks5Response}.
|
||||||
*
|
*
|
||||||
* @see SocksV5InitResponse
|
* @see Socks5InitResponse
|
||||||
* @see SocksV5AuthResponse
|
* @see Socks5AuthResponse
|
||||||
* @see SocksV5CmdResponse
|
* @see Socks5CmdResponse
|
||||||
* @see UnknownSocksV5Response
|
* @see UnknownSocks5Response
|
||||||
*/
|
*/
|
||||||
public abstract class SocksV5Response extends SocksResponse {
|
public abstract class Socks5Response extends SocksResponse {
|
||||||
private final SocksV5ResponseType responseType;
|
private final Socks5ResponseType responseType;
|
||||||
|
|
||||||
protected SocksV5Response(SocksV5ResponseType responseType) {
|
protected Socks5Response(Socks5ResponseType responseType) {
|
||||||
super(SocksProtocolVersion.SOCKS5);
|
super(SocksProtocolVersion.SOCKS5);
|
||||||
if (responseType == null) {
|
if (responseType == null) {
|
||||||
throw new NullPointerException("responseType");
|
throw new NullPointerException("responseType");
|
||||||
@ -48,7 +48,13 @@ public abstract class SocksV5Response extends SocksResponse {
|
|||||||
*
|
*
|
||||||
* @return socks response type
|
* @return socks response type
|
||||||
*/
|
*/
|
||||||
public SocksV5ResponseType responseType() {
|
public Socks5ResponseType responseType() {
|
||||||
return responseType;
|
return responseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We could have defined this method in {@link SocksMessage} as a protected method, but we did not,
|
||||||
|
* because we do not want to expose this method to users.
|
||||||
|
*/
|
||||||
|
abstract void encodeAsByteBuf(ByteBuf byteBuf);
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
/**
|
/**
|
||||||
* Type of socks response
|
* Type of socks response
|
||||||
*/
|
*/
|
||||||
public enum SocksV5ResponseType {
|
public enum Socks5ResponseType {
|
||||||
INIT,
|
INIT,
|
||||||
AUTH,
|
AUTH,
|
||||||
CMD,
|
CMD,
|
@ -16,18 +16,18 @@
|
|||||||
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
public enum SocksV5SubnegotiationVersion {
|
public enum Socks5SubnegotiationVersion {
|
||||||
AUTH_PASSWORD((byte) 0x01),
|
AUTH_PASSWORD((byte) 0x01),
|
||||||
UNKNOWN((byte) 0xff);
|
UNKNOWN((byte) 0xff);
|
||||||
|
|
||||||
private final byte b;
|
private final byte b;
|
||||||
|
|
||||||
SocksV5SubnegotiationVersion(byte b) {
|
Socks5SubnegotiationVersion(byte b) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SocksV5SubnegotiationVersion valueOf(byte b) {
|
public static Socks5SubnegotiationVersion valueOf(byte b) {
|
||||||
for (SocksV5SubnegotiationVersion code : values()) {
|
for (Socks5SubnegotiationVersion code : values()) {
|
||||||
if (code.b == b) {
|
if (code.b == b) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unknown socks request.
|
||||||
|
*
|
||||||
|
* @see Socks5InitRequestDecoder
|
||||||
|
* @see Socks5AuthRequestDecoder
|
||||||
|
* @see Socks5CmdRequestDecoder
|
||||||
|
*/
|
||||||
|
public final class UnknownSocks5Request extends Socks5Request {
|
||||||
|
|
||||||
|
public static final UnknownSocks5Request INSTANCE = new UnknownSocks5Request();
|
||||||
|
|
||||||
|
private UnknownSocks5Request() {
|
||||||
|
super(Socks5RequestType.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package io.netty.handler.codec.socksx.v5;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unknown socks response.
|
||||||
|
*
|
||||||
|
* @see Socks5InitResponseDecoder
|
||||||
|
* @see Socks5AuthResponseDecoder
|
||||||
|
* @see Socks5CmdResponseDecoder
|
||||||
|
*/
|
||||||
|
public final class UnknownSocks5Response extends Socks5Response {
|
||||||
|
|
||||||
|
public static final UnknownSocks5Response INSTANCE = new UnknownSocks5Response();
|
||||||
|
|
||||||
|
private UnknownSocks5Response() {
|
||||||
|
super(Socks5ResponseType.UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void encodeAsByteBuf(ByteBuf byteBuf) {
|
||||||
|
// NOOP
|
||||||
|
}
|
||||||
|
}
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An unknown socks request.
|
|
||||||
*
|
|
||||||
* @see SocksV5InitRequestDecoder
|
|
||||||
* @see SocksV5AuthRequestDecoder
|
|
||||||
* @see SocksV5CmdRequestDecoder
|
|
||||||
*/
|
|
||||||
public final class UnknownSocksV5Request extends SocksV5Request {
|
|
||||||
|
|
||||||
public UnknownSocksV5Request() {
|
|
||||||
super(SocksV5RequestType.UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
|
||||||
// NOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class UnknownSocksV5RequestHolder {
|
|
||||||
public static final UnknownSocksV5Request HOLDER_INSTANCE = new UnknownSocksV5Request();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnknownSocksV5Request getInstance() {
|
|
||||||
return UnknownSocksV5RequestHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.handler.codec.socksx.v5;
|
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An unknown socks response.
|
|
||||||
*
|
|
||||||
* @see SocksV5InitResponseDecoder
|
|
||||||
* @see SocksV5AuthResponseDecoder
|
|
||||||
* @see SocksV5CmdResponseDecoder
|
|
||||||
*/
|
|
||||||
public final class UnknownSocksV5Response extends SocksV5Response {
|
|
||||||
|
|
||||||
public UnknownSocksV5Response() {
|
|
||||||
super(SocksV5ResponseType.UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void encodeAsByteBuf(ByteBuf byteBuf) {
|
|
||||||
// NOOP
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class UnknownSocksV5ResponseHolder {
|
|
||||||
public static final UnknownSocksV5Response HOLDER_INSTANCE = new UnknownSocksV5Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnknownSocksV5Response getInstance() {
|
|
||||||
return UnknownSocksV5ResponseHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encoder, decoder and their related message types for Socks.
|
* Encoder, decoder and their related message types for SOCKSv5 protocol.
|
||||||
*/
|
*/
|
||||||
package io.netty.handler.codec.socksx.v5;
|
package io.netty.handler.codec.socksx.v5;
|
||||||
// TODO: Combine decoders into one.
|
|
||||||
|
@ -16,35 +16,27 @@
|
|||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AddressType;
|
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest;
|
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdType;
|
|
||||||
import io.netty.handler.codec.socksx.v5.UnknownSocksV5Request;
|
|
||||||
import io.netty.util.internal.SystemPropertyUtil;
|
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertSame;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class SocksV4CmdRequestDecoderTest {
|
public class Socks4CmdRequestDecoderTest {
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV4CmdRequestDecoderTest.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks4CmdRequestDecoderTest.class);
|
||||||
|
|
||||||
private static void testSocksV4CmdRequestDecoderWithDifferentParams(String userId,
|
private static void testSocksV4CmdRequestDecoderWithDifferentParams(String userId,
|
||||||
SocksV4CmdType cmdType,
|
Socks4CmdType cmdType,
|
||||||
String host,
|
String host,
|
||||||
int port) {
|
int port) {
|
||||||
logger.debug("Testing cmdType: " + cmdType + " userId: " + userId + " host: " + host +
|
logger.debug("Testing cmdType: " + cmdType + " userId: " + userId + " host: " + host +
|
||||||
" port: " + port);
|
" port: " + port);
|
||||||
SocksV4CmdRequest msg = new SocksV4CmdRequest(userId, cmdType, host, port);
|
Socks4CmdRequest msg = new Socks4CmdRequest(userId, cmdType, host, port);
|
||||||
SocksV4CmdRequestDecoder decoder = new SocksV4CmdRequestDecoder();
|
Socks4CmdRequestDecoder decoder = new Socks4CmdRequestDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
Object obj = embedder.readInbound();
|
Object obj = embedder.readInbound();
|
||||||
msg = (SocksV4CmdRequest) obj;
|
msg = (Socks4CmdRequest) obj;
|
||||||
assertSame(msg.cmdType(), cmdType);
|
assertSame(msg.cmdType(), cmdType);
|
||||||
assertEquals(msg.userId(), userId);
|
assertEquals(msg.userId(), userId);
|
||||||
assertEquals(msg.host(), host);
|
assertEquals(msg.host(), host);
|
||||||
@ -57,7 +49,7 @@ public class SocksV4CmdRequestDecoderTest {
|
|||||||
String[] hosts = {"127.0.0.1", };
|
String[] hosts = {"127.0.0.1", };
|
||||||
String[] userIds = {"test", };
|
String[] userIds = {"test", };
|
||||||
int[] ports = {1, 32769, 65535};
|
int[] ports = {1, 32769, 65535};
|
||||||
for (SocksV4CmdType cmdType : SocksV4CmdType.values()) {
|
for (Socks4CmdType cmdType : Socks4CmdType.values()) {
|
||||||
for (String userId : userIds) {
|
for (String userId : userIds) {
|
||||||
for (String host : hosts) {
|
for (String host : hosts) {
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
@ -18,6 +18,6 @@ package io.netty.handler.codec.socksx.v4;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SocksV4CmdRequestTest {
|
public class Socks4CmdRequestTest {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdRequestTest.class);
|
private static final Logger logger = LoggerFactory.getLogger(Socks4CmdRequestTest.class);
|
||||||
}
|
}
|
@ -16,33 +16,29 @@
|
|||||||
package io.netty.handler.codec.socksx.v4;
|
package io.netty.handler.codec.socksx.v4;
|
||||||
|
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AddressType;
|
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdStatus;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.*;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class SocksV4CmdResponseDecoderTest {
|
public class Socks4CmdResponseDecoderTest {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdResponseDecoderTest.class);
|
private static final Logger logger = LoggerFactory.getLogger(Socks4CmdResponseDecoderTest.class);
|
||||||
|
|
||||||
private static void testSocksCmdResponseDecoderWithDifferentParams(
|
private static void testSocksCmdResponseDecoderWithDifferentParams(
|
||||||
SocksV4CmdStatus cmdStatus, String host, int port) {
|
Socks4CmdStatus cmdStatus, String host, int port) {
|
||||||
logger.debug("Testing cmdStatus: " + cmdStatus);
|
logger.debug("Testing cmdStatus: " + cmdStatus);
|
||||||
SocksV4Response msg = new SocksV4CmdResponse(cmdStatus, host, port);
|
Socks4Response msg = new Socks4CmdResponse(cmdStatus, host, port);
|
||||||
SocksV4CmdResponseDecoder decoder = new SocksV4CmdResponseDecoder();
|
Socks4CmdResponseDecoder decoder = new Socks4CmdResponseDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks4CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
|
|
||||||
msg = (SocksV4Response) embedder.readInbound();
|
msg = (Socks4Response) embedder.readInbound();
|
||||||
assertEquals(((SocksV4CmdResponse) msg).cmdStatus(), cmdStatus);
|
assertEquals(((Socks4CmdResponse) msg).cmdStatus(), cmdStatus);
|
||||||
if (host != null) {
|
if (host != null) {
|
||||||
assertEquals(((SocksV4CmdResponse) msg).host(), host);
|
assertEquals(((Socks4CmdResponse) msg).host(), host);
|
||||||
}
|
}
|
||||||
assertEquals(((SocksV4CmdResponse) msg).port(), port);
|
assertEquals(((Socks4CmdResponse) msg).port(), port);
|
||||||
assertNull(embedder.readInbound());
|
assertNull(embedder.readInbound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +47,7 @@ public class SocksV4CmdResponseDecoderTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocksCmdResponseDecoder() {
|
public void testSocksCmdResponseDecoder() {
|
||||||
for (SocksV4CmdStatus cmdStatus : SocksV4CmdStatus.values()) {
|
for (Socks4CmdStatus cmdStatus : Socks4CmdStatus.values()) {
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, null, 0);
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, null, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,6 +18,6 @@ package io.netty.handler.codec.socksx.v4;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SocksV4CmdResponseTest {
|
public class Socks4CmdResponseTest {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SocksV4CmdResponseTest.class);
|
private static final Logger logger = LoggerFactory.getLogger(Socks4CmdResponseTest.class);
|
||||||
}
|
}
|
@ -18,18 +18,22 @@ package io.netty.handler.codec.socksx.v4;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
|
||||||
|
|
||||||
final class SocksV4CommonTestUtils {
|
final class Socks4CommonTestUtils {
|
||||||
/**
|
/**
|
||||||
* A constructor to stop this class being constructed.
|
* A constructor to stop this class being constructed.
|
||||||
*/
|
*/
|
||||||
private SocksV4CommonTestUtils() {
|
private Socks4CommonTestUtils() {
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks4Request msg) {
|
||||||
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, SocksMessage msg) {
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
msg.encodeAsByteBuf(buf);
|
||||||
|
embedder.writeInbound(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks4Response msg) {
|
||||||
ByteBuf buf = Unpooled.buffer();
|
ByteBuf buf = Unpooled.buffer();
|
||||||
msg.encodeAsByteBuf(buf);
|
msg.encodeAsByteBuf(buf);
|
||||||
embedder.writeInbound(buf);
|
embedder.writeInbound(buf);
|
@ -20,17 +20,17 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5AuthRequestDecoderTest {
|
public class Socks5AuthRequestDecoderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthRequestDecoder() {
|
public void testAuthRequestDecoder() {
|
||||||
String username = "test";
|
String username = "test";
|
||||||
String password = "test";
|
String password = "test";
|
||||||
SocksV5AuthRequest msg = new SocksV5AuthRequest(username, password);
|
Socks5AuthRequest msg = new Socks5AuthRequest(username, password);
|
||||||
SocksV5AuthRequestDecoder decoder = new SocksV5AuthRequestDecoder();
|
Socks5AuthRequestDecoder decoder = new Socks5AuthRequestDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
msg = (SocksV5AuthRequest) embedder.readInbound();
|
msg = (Socks5AuthRequest) embedder.readInbound();
|
||||||
assertEquals(msg.username(), username);
|
assertEquals(msg.username(), username);
|
||||||
assertEquals(msg.username(), password);
|
assertEquals(msg.username(), password);
|
||||||
assertNull(embedder.readInbound());
|
assertNull(embedder.readInbound());
|
@ -18,16 +18,16 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SocksV5AuthRequestTest {
|
public class Socks5AuthRequestTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest(null, "");
|
new Socks5AuthRequest(null, "");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest("", null);
|
new Socks5AuthRequest("", null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
@ -36,12 +36,12 @@ public class SocksV5AuthRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testUsernameOrPasswordIsNotAscii() {
|
public void testUsernameOrPasswordIsNotAscii() {
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest("παράδειγμα.δοκιμή", "password");
|
new Socks5AuthRequest("παράδειγμα.δοκιμή", "password");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest("username", "παράδειγμα.δοκιμή");
|
new Socks5AuthRequest("username", "παράδειγμα.δοκιμή");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ public class SocksV5AuthRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testUsernameOrPasswordLengthIsLessThan255Chars() {
|
public void testUsernameOrPasswordLengthIsLessThan255Chars() {
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest(
|
new Socks5AuthRequest(
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||||
@ -64,7 +64,7 @@ public class SocksV5AuthRequestTest {
|
|||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthRequest("password",
|
new Socks5AuthRequest("password",
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
||||||
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
"passwordpasswordpasswordpasswordpasswordpasswordpassword" +
|
@ -22,24 +22,24 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5AuthResponseDecoderTest {
|
public class Socks5AuthResponseDecoderTest {
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(
|
||||||
SocksV5AuthResponseDecoderTest.class);
|
Socks5AuthResponseDecoderTest.class);
|
||||||
|
|
||||||
private static void testSocksAuthResponseDecoderWithDifferentParams(SocksV5AuthStatus authStatus) {
|
private static void testSocksAuthResponseDecoderWithDifferentParams(Socks5AuthStatus authStatus) {
|
||||||
logger.debug("Testing SocksAuthResponseDecoder with authStatus: " + authStatus);
|
logger.debug("Testing SocksAuthResponseDecoder with authStatus: " + authStatus);
|
||||||
SocksV5AuthResponse msg = new SocksV5AuthResponse(authStatus);
|
Socks5AuthResponse msg = new Socks5AuthResponse(authStatus);
|
||||||
SocksV5AuthResponseDecoder decoder = new SocksV5AuthResponseDecoder();
|
Socks5AuthResponseDecoder decoder = new Socks5AuthResponseDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
msg = (SocksV5AuthResponse) embedder.readInbound();
|
msg = (Socks5AuthResponse) embedder.readInbound();
|
||||||
assertSame(msg.authStatus(), authStatus);
|
assertSame(msg.authStatus(), authStatus);
|
||||||
assertNull(embedder.readInbound());
|
assertNull(embedder.readInbound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSocksCmdResponseDecoder() {
|
public void testSocksCmdResponseDecoder() {
|
||||||
for (SocksV5AuthStatus authStatus: SocksV5AuthStatus.values()) {
|
for (Socks5AuthStatus authStatus: Socks5AuthStatus.values()) {
|
||||||
testSocksAuthResponseDecoderWithDifferentParams(authStatus);
|
testSocksAuthResponseDecoderWithDifferentParams(authStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SocksV5AuthResponseTest {
|
public class Socks5AuthResponseTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5AuthResponse(null);
|
new Socks5AuthResponse(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
@ -23,23 +23,23 @@ import sun.net.util.IPAddressUtil;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5CmdRequestDecoderTest {
|
public class Socks5CmdRequestDecoderTest {
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV5CmdRequestDecoderTest.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks5CmdRequestDecoderTest.class);
|
||||||
|
|
||||||
private static void testSocksCmdRequestDecoderWithDifferentParams(SocksV5CmdType cmdType,
|
private static void testSocksCmdRequestDecoderWithDifferentParams(Socks5CmdType cmdType,
|
||||||
SocksV5AddressType addressType,
|
Socks5AddressType addressType,
|
||||||
String host,
|
String host,
|
||||||
int port) {
|
int port) {
|
||||||
logger.debug("Testing cmdType: " + cmdType + " addressType: " + addressType + " host: " + host +
|
logger.debug("Testing cmdType: " + cmdType + " addressType: " + addressType + " host: " + host +
|
||||||
" port: " + port);
|
" port: " + port);
|
||||||
SocksV5CmdRequest msg = new SocksV5CmdRequest(cmdType, addressType, host, port);
|
Socks5CmdRequest msg = new Socks5CmdRequest(cmdType, addressType, host, port);
|
||||||
SocksV5CmdRequestDecoder decoder = new SocksV5CmdRequestDecoder();
|
Socks5CmdRequestDecoder decoder = new Socks5CmdRequestDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
if (msg.addressType() == SocksV5AddressType.UNKNOWN) {
|
if (msg.addressType() == Socks5AddressType.UNKNOWN) {
|
||||||
assertTrue(embedder.readInbound() instanceof UnknownSocksV5Request);
|
assertTrue(embedder.readInbound() instanceof UnknownSocks5Request);
|
||||||
} else {
|
} else {
|
||||||
msg = (SocksV5CmdRequest) embedder.readInbound();
|
msg = (Socks5CmdRequest) embedder.readInbound();
|
||||||
assertSame(msg.cmdType(), cmdType);
|
assertSame(msg.cmdType(), cmdType);
|
||||||
assertSame(msg.addressType(), addressType);
|
assertSame(msg.addressType(), addressType);
|
||||||
assertEquals(msg.host(), host);
|
assertEquals(msg.host(), host);
|
||||||
@ -52,10 +52,10 @@ public class SocksV5CmdRequestDecoderTest {
|
|||||||
public void testCmdRequestDecoderIPv4() {
|
public void testCmdRequestDecoderIPv4() {
|
||||||
String[] hosts = {"127.0.0.1", };
|
String[] hosts = {"127.0.0.1", };
|
||||||
int[] ports = {1, 32769, 65535 };
|
int[] ports = {1, 32769, 65535 };
|
||||||
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) {
|
for (Socks5CmdType cmdType : Socks5CmdType.values()) {
|
||||||
for (String host : hosts) {
|
for (String host : hosts) {
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.IPv4, host, port);
|
testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.IPv4, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,12 +63,12 @@ public class SocksV5CmdRequestDecoderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCmdRequestDecoderIPv6() {
|
public void testCmdRequestDecoderIPv6() {
|
||||||
String[] hosts = {SocksV5CommonUtils.ipv6toStr(IPAddressUtil.textToNumericFormatV6("::1"))};
|
String[] hosts = { Socks5CommonUtils.ipv6toStr(IPAddressUtil.textToNumericFormatV6("::1"))};
|
||||||
int[] ports = {1, 32769, 65535};
|
int[] ports = {1, 32769, 65535};
|
||||||
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) {
|
for (Socks5CmdType cmdType : Socks5CmdType.values()) {
|
||||||
for (String host : hosts) {
|
for (String host : hosts) {
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.IPv6, host, port);
|
testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.IPv6, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,10 +89,10 @@ public class SocksV5CmdRequestDecoderTest {
|
|||||||
"실례.테스트",
|
"실례.테스트",
|
||||||
"உதாரணம்.பரிட்சை"};
|
"உதாரணம்.பரிட்சை"};
|
||||||
int[] ports = {1, 32769, 65535};
|
int[] ports = {1, 32769, 65535};
|
||||||
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) {
|
for (Socks5CmdType cmdType : Socks5CmdType.values()) {
|
||||||
for (String host : hosts) {
|
for (String host : hosts) {
|
||||||
for (int port : ports) {
|
for (int port : ports) {
|
||||||
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.DOMAIN, host, port);
|
testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.DOMAIN, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,8 +102,8 @@ public class SocksV5CmdRequestDecoderTest {
|
|||||||
public void testCmdRequestDecoderUnknown() {
|
public void testCmdRequestDecoderUnknown() {
|
||||||
String host = "google.com";
|
String host = "google.com";
|
||||||
int port = 80;
|
int port = 80;
|
||||||
for (SocksV5CmdType cmdType : SocksV5CmdType.values()) {
|
for (Socks5CmdType cmdType : Socks5CmdType.values()) {
|
||||||
testSocksCmdRequestDecoderWithDifferentParams(cmdType, SocksV5AddressType.UNKNOWN, host, port);
|
testSocksCmdRequestDecoderWithDifferentParams(cmdType, Socks5AddressType.UNKNOWN, host, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -19,23 +19,23 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5CmdRequestTest {
|
public class Socks5CmdRequestTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(null, SocksV5AddressType.UNKNOWN, "", 1);
|
new Socks5CmdRequest(null, Socks5AddressType.UNKNOWN, "", 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.UNKNOWN, null, "", 1);
|
new Socks5CmdRequest(Socks5CmdType.UNKNOWN, null, "", 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.UNKNOWN, SocksV5AddressType.UNKNOWN, null, 1);
|
new Socks5CmdRequest(Socks5CmdType.UNKNOWN, Socks5AddressType.UNKNOWN, null, 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ public class SocksV5CmdRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testIPv4CorrectAddress() {
|
public void testIPv4CorrectAddress() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.IPv4, "54.54.1111.253", 1);
|
new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.IPv4, "54.54.1111.253", 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ public class SocksV5CmdRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testIPv6CorrectAddress() {
|
public void testIPv6CorrectAddress() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.IPv6, "xxx:xxx:xxx", 1);
|
new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.IPv6, "xxx:xxx:xxx", 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ public class SocksV5CmdRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testIDNNotExceeds255CharsLimit() {
|
public void testIDNNotExceeds255CharsLimit() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN,
|
new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
|
||||||
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
||||||
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
||||||
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
"παράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμήπαράδειγμα.δοκιμή" +
|
||||||
@ -75,14 +75,14 @@ public class SocksV5CmdRequestTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testValidPortRange() {
|
public void testValidPortRange() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN,
|
new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
|
||||||
"παράδειγμα.δοκιμήπαράδει", 0);
|
"παράδειγμα.δοκιμήπαράδει", 0);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdRequest(SocksV5CmdType.BIND, SocksV5AddressType.DOMAIN,
|
new Socks5CmdRequest(Socks5CmdType.BIND, Socks5AddressType.DOMAIN,
|
||||||
"παράδειγμα.δοκιμήπαράδει", 65536);
|
"παράδειγμα.δοκιμήπαράδει", 65536);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
@ -22,25 +22,25 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5CmdResponseDecoderTest {
|
public class Socks5CmdResponseDecoderTest {
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksV5CmdResponseDecoderTest.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Socks5CmdResponseDecoderTest.class);
|
||||||
|
|
||||||
private static void testSocksCmdResponseDecoderWithDifferentParams(
|
private static void testSocksCmdResponseDecoderWithDifferentParams(
|
||||||
SocksV5CmdStatus cmdStatus, SocksV5AddressType addressType, String host, int port) {
|
Socks5CmdStatus cmdStatus, Socks5AddressType addressType, String host, int port) {
|
||||||
logger.debug("Testing cmdStatus: " + cmdStatus + " addressType: " + addressType);
|
logger.debug("Testing cmdStatus: " + cmdStatus + " addressType: " + addressType);
|
||||||
SocksV5Response msg = new SocksV5CmdResponse(cmdStatus, addressType, host, port);
|
Socks5Response msg = new Socks5CmdResponse(cmdStatus, addressType, host, port);
|
||||||
SocksV5CmdResponseDecoder decoder = new SocksV5CmdResponseDecoder();
|
Socks5CmdResponseDecoder decoder = new Socks5CmdResponseDecoder();
|
||||||
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
EmbeddedChannel embedder = new EmbeddedChannel(decoder);
|
||||||
SocksV5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
Socks5CommonTestUtils.writeMessageIntoEmbedder(embedder, msg);
|
||||||
if (addressType == SocksV5AddressType.UNKNOWN) {
|
if (addressType == Socks5AddressType.UNKNOWN) {
|
||||||
assertTrue(embedder.readInbound() instanceof UnknownSocksV5Response);
|
assertTrue(embedder.readInbound() instanceof UnknownSocks5Response);
|
||||||
} else {
|
} else {
|
||||||
msg = (SocksV5Response) embedder.readInbound();
|
msg = (Socks5Response) embedder.readInbound();
|
||||||
assertEquals(((SocksV5CmdResponse) msg).cmdStatus(), cmdStatus);
|
assertEquals(((Socks5CmdResponse) msg).cmdStatus(), cmdStatus);
|
||||||
if (host != null) {
|
if (host != null) {
|
||||||
assertEquals(((SocksV5CmdResponse) msg).host(), host);
|
assertEquals(((Socks5CmdResponse) msg).host(), host);
|
||||||
}
|
}
|
||||||
assertEquals(((SocksV5CmdResponse) msg).port(), port);
|
assertEquals(((Socks5CmdResponse) msg).port(), port);
|
||||||
}
|
}
|
||||||
assertNull(embedder.readInbound());
|
assertNull(embedder.readInbound());
|
||||||
}
|
}
|
||||||
@ -50,8 +50,8 @@ public class SocksV5CmdResponseDecoderTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocksCmdResponseDecoder() {
|
public void testSocksCmdResponseDecoder() {
|
||||||
for (SocksV5CmdStatus cmdStatus : SocksV5CmdStatus.values()) {
|
for (Socks5CmdStatus cmdStatus : Socks5CmdStatus.values()) {
|
||||||
for (SocksV5AddressType addressType : SocksV5AddressType.values()) {
|
for (Socks5AddressType addressType : Socks5AddressType.values()) {
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, addressType, null, 0);
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, addressType, null, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ public class SocksV5CmdResponseDecoderTest {
|
|||||||
*/
|
*/
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testInvalidAddress() {
|
public void testInvalidAddress() {
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "1", 80);
|
testSocksCmdResponseDecoderWithDifferentParams(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "1", 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,14 +70,14 @@ public class SocksV5CmdResponseDecoderTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testSocksCmdResponseDecoderIncludingHost() {
|
public void testSocksCmdResponseDecoderIncludingHost() {
|
||||||
for (SocksV5CmdStatus cmdStatus : SocksV5CmdStatus.values()) {
|
for (Socks5CmdStatus cmdStatus : Socks5CmdStatus.values()) {
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv4,
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv4,
|
||||||
"127.0.0.1", 80);
|
"127.0.0.1", 80);
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.DOMAIN,
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.DOMAIN,
|
||||||
"testDomain.com", 80);
|
"testDomain.com", 80);
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv6,
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv6,
|
||||||
"2001:db8:85a3:42:1000:8a2e:370:7334", 80);
|
"2001:db8:85a3:42:1000:8a2e:370:7334", 80);
|
||||||
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, SocksV5AddressType.IPv6,
|
testSocksCmdResponseDecoderWithDifferentParams(cmdStatus, Socks5AddressType.IPv6,
|
||||||
"1111:111:11:1:0:0:0:1", 80);
|
"1111:111:11:1:0:0:0:1", 80);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,16 +21,16 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class SocksV5CmdResponseTest {
|
public class Socks5CmdResponseTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdResponse(null, SocksV5AddressType.UNKNOWN);
|
new Socks5CmdResponse(null, Socks5AddressType.UNKNOWN);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.UNASSIGNED, null);
|
new Socks5CmdResponse(Socks5CmdStatus.UNASSIGNED, null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
||||||
@ -41,12 +41,12 @@ public class SocksV5CmdResponseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyDomain() {
|
public void testEmptyDomain() {
|
||||||
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse(
|
Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
|
||||||
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.DOMAIN);
|
Socks5CmdStatus.SUCCESS, Socks5AddressType.DOMAIN);
|
||||||
assertNull(socksV5CmdResponse.host());
|
assertNull(socks5CmdResponse.host());
|
||||||
assertEquals(0, socksV5CmdResponse.port());
|
assertEquals(0, socks5CmdResponse.port());
|
||||||
ByteBuf buffer = Unpooled.buffer(20);
|
ByteBuf buffer = Unpooled.buffer(20);
|
||||||
socksV5CmdResponse.encodeAsByteBuf(buffer);
|
socks5CmdResponse.encodeAsByteBuf(buffer);
|
||||||
byte[] expected = {
|
byte[] expected = {
|
||||||
0x05, // version
|
0x05, // version
|
||||||
0x00, // success reply
|
0x00, // success reply
|
||||||
@ -65,12 +65,12 @@ public class SocksV5CmdResponseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testIPv4Host() {
|
public void testIPv4Host() {
|
||||||
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse(
|
Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
|
||||||
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0.1", 80);
|
Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0.1", 80);
|
||||||
assertEquals("127.0.0.1", socksV5CmdResponse.host());
|
assertEquals("127.0.0.1", socks5CmdResponse.host());
|
||||||
assertEquals(80, socksV5CmdResponse.port());
|
assertEquals(80, socks5CmdResponse.port());
|
||||||
ByteBuf buffer = Unpooled.buffer(20);
|
ByteBuf buffer = Unpooled.buffer(20);
|
||||||
socksV5CmdResponse.encodeAsByteBuf(buffer);
|
socks5CmdResponse.encodeAsByteBuf(buffer);
|
||||||
byte[] expected = {
|
byte[] expected = {
|
||||||
0x05, // version
|
0x05, // version
|
||||||
0x00, // success reply
|
0x00, // success reply
|
||||||
@ -91,12 +91,12 @@ public class SocksV5CmdResponseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testEmptyBoundAddress() {
|
public void testEmptyBoundAddress() {
|
||||||
SocksV5CmdResponse socksV5CmdResponse = new SocksV5CmdResponse(
|
Socks5CmdResponse socks5CmdResponse = new Socks5CmdResponse(
|
||||||
SocksV5CmdStatus.SUCCESS, SocksV5AddressType.DOMAIN, "", 80);
|
Socks5CmdStatus.SUCCESS, Socks5AddressType.DOMAIN, "", 80);
|
||||||
assertEquals("", socksV5CmdResponse.host());
|
assertEquals("", socks5CmdResponse.host());
|
||||||
assertEquals(80, socksV5CmdResponse.port());
|
assertEquals(80, socks5CmdResponse.port());
|
||||||
ByteBuf buffer = Unpooled.buffer(20);
|
ByteBuf buffer = Unpooled.buffer(20);
|
||||||
socksV5CmdResponse.encodeAsByteBuf(buffer);
|
socks5CmdResponse.encodeAsByteBuf(buffer);
|
||||||
byte[] expected = {
|
byte[] expected = {
|
||||||
0x05, // version
|
0x05, // version
|
||||||
0x00, // success reply
|
0x00, // success reply
|
||||||
@ -114,7 +114,7 @@ public class SocksV5CmdResponseTest {
|
|||||||
*/
|
*/
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testInvalidBoundAddress() {
|
public void testInvalidBoundAddress() {
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 1000);
|
new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assertByteBufEquals(byte[] expected, ByteBuf actual) {
|
private static void assertByteBufEquals(byte[] expected, ByteBuf actual) {
|
||||||
@ -127,13 +127,13 @@ public class SocksV5CmdResponseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testValidPortRange() {
|
public void testValidPortRange() {
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 0);
|
new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 0);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, SocksV5AddressType.IPv4, "127.0.0", 65536);
|
new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, Socks5AddressType.IPv4, "127.0.0", 65536);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof IllegalArgumentException);
|
assertTrue(e instanceof IllegalArgumentException);
|
||||||
}
|
}
|
@ -18,18 +18,22 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.channel.embedded.EmbeddedChannel;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
|
||||||
|
|
||||||
final class SocksV5CommonTestUtils {
|
final class Socks5CommonTestUtils {
|
||||||
/**
|
/**
|
||||||
* A constructor to stop this class being constructed.
|
* A constructor to stop this class being constructed.
|
||||||
*/
|
*/
|
||||||
private SocksV5CommonTestUtils() {
|
private Socks5CommonTestUtils() {
|
||||||
//NOOP
|
//NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks5Request msg) {
|
||||||
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, SocksMessage msg) {
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
msg.encodeAsByteBuf(buf);
|
||||||
|
embedder.writeInbound(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeMessageIntoEmbedder(EmbeddedChannel embedder, Socks5Response msg) {
|
||||||
ByteBuf buf = Unpooled.buffer();
|
ByteBuf buf = Unpooled.buffer();
|
||||||
msg.encodeAsByteBuf(buf);
|
msg.encodeAsByteBuf(buf);
|
||||||
embedder.writeInbound(buf);
|
embedder.writeInbound(buf);
|
@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SocksV5InitRequestTest {
|
public class Socks5InitRequestTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5InitRequest(null);
|
new Socks5InitRequest(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
@ -18,11 +18,11 @@ package io.netty.handler.codec.socksx.v5;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class SocksV5InitResponseTest {
|
public class Socks5InitResponseTest {
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorParamsAreNotNull() {
|
public void testConstructorParamsAreNotNull() {
|
||||||
try {
|
try {
|
||||||
new SocksV5InitResponse(null);
|
new Socks5InitResponse(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertTrue(e instanceof NullPointerException);
|
assertTrue(e instanceof NullPointerException);
|
||||||
}
|
}
|
@ -19,10 +19,11 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||||
import io.netty.handler.codec.socksx.SocksMessageEncoder;
|
|
||||||
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
import io.netty.handler.codec.socksx.SocksProtocolVersion;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequestDecoder;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdRequestDecoder;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5InitRequestDecoder;
|
import io.netty.handler.codec.socksx.v4.Socks4MessageEncoder;
|
||||||
|
import io.netty.handler.codec.socksx.v5.Socks5InitRequestDecoder;
|
||||||
|
import io.netty.handler.codec.socksx.v5.Socks5MessageEncoder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -35,18 +36,21 @@ public class SocksPortUnificationServerHandler extends ByteToMessageDecoder {
|
|||||||
in.resetReaderIndex();
|
in.resetReaderIndex();
|
||||||
switch (version) {
|
switch (version) {
|
||||||
case SOCKS4a:
|
case SOCKS4a:
|
||||||
p.addLast(new SocksV4CmdRequestDecoder());
|
p.addLast(new Socks4CmdRequestDecoder());
|
||||||
|
p.addLast(Socks4MessageEncoder.INSTANCE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case SOCKS5:
|
case SOCKS5:
|
||||||
p.addLast(new SocksV5InitRequestDecoder());
|
p.addLast(new Socks5InitRequestDecoder());
|
||||||
|
p.addLast(Socks5MessageEncoder.INSTANCE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
in.clear();
|
in.clear();
|
||||||
ctx.close();
|
ctx.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p.addLast(SocksMessageEncoder.getInstance());
|
p.addLast(SocksServerHandler.INSTANCE);
|
||||||
p.addLast(SocksServerHandler.getInstance());
|
|
||||||
p.remove(this);
|
p.remove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,17 +24,13 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
import io.netty.handler.codec.socks.SocksCmdRequest;
|
|
||||||
import io.netty.handler.codec.socks.SocksCmdResponse;
|
|
||||||
import io.netty.handler.codec.socks.SocksCmdStatus;
|
|
||||||
import io.netty.handler.codec.socksx.SocksMessage;
|
|
||||||
import io.netty.handler.codec.socksx.SocksRequest;
|
import io.netty.handler.codec.socksx.SocksRequest;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequest;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdRequest;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdResponse;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdResponse;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdStatus;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdStatus;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdRequest;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdResponse;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdResponse;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdStatus;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdStatus;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
import io.netty.util.concurrent.Promise;
|
import io.netty.util.concurrent.Promise;
|
||||||
@ -46,8 +42,8 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead0(final ChannelHandlerContext ctx, final SocksRequest message) throws Exception {
|
public void channelRead0(final ChannelHandlerContext ctx, final SocksRequest message) throws Exception {
|
||||||
if (message instanceof SocksV4CmdRequest) {
|
if (message instanceof Socks4CmdRequest) {
|
||||||
final SocksV4CmdRequest request = (SocksV4CmdRequest) message;
|
final Socks4CmdRequest request = (Socks4CmdRequest) message;
|
||||||
Promise<Channel> promise = ctx.executor().newPromise();
|
Promise<Channel> promise = ctx.executor().newPromise();
|
||||||
promise.addListener(
|
promise.addListener(
|
||||||
new GenericFutureListener<Future<Channel>>() {
|
new GenericFutureListener<Future<Channel>>() {
|
||||||
@ -55,7 +51,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
public void operationComplete(final Future<Channel> future) throws Exception {
|
public void operationComplete(final Future<Channel> future) throws Exception {
|
||||||
final Channel outboundChannel = future.getNow();
|
final Channel outboundChannel = future.getNow();
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
ctx.channel().writeAndFlush(new SocksV4CmdResponse(SocksV4CmdStatus.SUCCESS))
|
ctx.channel().writeAndFlush(new Socks4CmdResponse(Socks4CmdStatus.SUCCESS))
|
||||||
.addListener(new ChannelFutureListener() {
|
.addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture channelFuture) {
|
public void operationComplete(ChannelFuture channelFuture) {
|
||||||
@ -66,7 +62,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ctx.channel().writeAndFlush(
|
ctx.channel().writeAndFlush(
|
||||||
new SocksV4CmdResponse(SocksV4CmdStatus.REJECTED_OR_FAILED)
|
new Socks4CmdResponse(Socks4CmdStatus.REJECTED_OR_FAILED)
|
||||||
);
|
);
|
||||||
SocksServerUtils.closeOnFlush(ctx.channel());
|
SocksServerUtils.closeOnFlush(ctx.channel());
|
||||||
}
|
}
|
||||||
@ -88,14 +84,14 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
} else {
|
} else {
|
||||||
// Close the connection if the connection attempt has failed.
|
// Close the connection if the connection attempt has failed.
|
||||||
ctx.channel().writeAndFlush(
|
ctx.channel().writeAndFlush(
|
||||||
new SocksV4CmdResponse(SocksV4CmdStatus.REJECTED_OR_FAILED)
|
new Socks4CmdResponse(Socks4CmdStatus.REJECTED_OR_FAILED)
|
||||||
);
|
);
|
||||||
SocksServerUtils.closeOnFlush(ctx.channel());
|
SocksServerUtils.closeOnFlush(ctx.channel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (message instanceof SocksV5CmdRequest) {
|
} else if (message instanceof Socks5CmdRequest) {
|
||||||
final SocksV5CmdRequest request = (SocksV5CmdRequest) message;
|
final Socks5CmdRequest request = (Socks5CmdRequest) message;
|
||||||
Promise<Channel> promise = ctx.executor().newPromise();
|
Promise<Channel> promise = ctx.executor().newPromise();
|
||||||
promise.addListener(
|
promise.addListener(
|
||||||
new GenericFutureListener<Future<Channel>>() {
|
new GenericFutureListener<Future<Channel>>() {
|
||||||
@ -104,7 +100,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
final Channel outboundChannel = future.getNow();
|
final Channel outboundChannel = future.getNow();
|
||||||
if (future.isSuccess()) {
|
if (future.isSuccess()) {
|
||||||
ctx.channel().writeAndFlush(
|
ctx.channel().writeAndFlush(
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.SUCCESS, request.addressType())
|
new Socks5CmdResponse(Socks5CmdStatus.SUCCESS, request.addressType())
|
||||||
).addListener(new ChannelFutureListener() {
|
).addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
public void operationComplete(ChannelFuture channelFuture) {
|
public void operationComplete(ChannelFuture channelFuture) {
|
||||||
@ -116,7 +112,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
ctx.channel().writeAndFlush(
|
ctx.channel().writeAndFlush(
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.FAILURE, request.addressType()));
|
new Socks5CmdResponse(Socks5CmdStatus.FAILURE, request.addressType()));
|
||||||
SocksServerUtils.closeOnFlush(ctx.channel());
|
SocksServerUtils.closeOnFlush(ctx.channel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +133,7 @@ public final class SocksServerConnectHandler extends SimpleChannelInboundHandler
|
|||||||
} else {
|
} else {
|
||||||
// Close the connection if the connection attempt has failed.
|
// Close the connection if the connection attempt has failed.
|
||||||
ctx.channel().writeAndFlush(
|
ctx.channel().writeAndFlush(
|
||||||
new SocksV5CmdResponse(SocksV5CmdStatus.FAILURE, request.addressType()));
|
new Socks5CmdResponse(Socks5CmdStatus.FAILURE, request.addressType()));
|
||||||
SocksServerUtils.closeOnFlush(ctx.channel());
|
SocksServerUtils.closeOnFlush(ctx.channel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,26 +19,30 @@ import io.netty.channel.ChannelHandler;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
import io.netty.handler.codec.socksx.SocksRequest;
|
import io.netty.handler.codec.socksx.SocksRequest;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdRequest;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdRequest;
|
||||||
import io.netty.handler.codec.socksx.v4.SocksV4CmdType;
|
import io.netty.handler.codec.socksx.v4.Socks4CmdType;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AuthScheme;
|
import io.netty.handler.codec.socksx.v5.Socks5AuthScheme;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequestDecoder;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdRequestDecoder;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5InitResponse;
|
import io.netty.handler.codec.socksx.v5.Socks5InitResponse;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5Request;
|
import io.netty.handler.codec.socksx.v5.Socks5Request;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AuthResponse;
|
import io.netty.handler.codec.socksx.v5.Socks5AuthResponse;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5AuthStatus;
|
import io.netty.handler.codec.socksx.v5.Socks5AuthStatus;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdRequest;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdRequest;
|
||||||
import io.netty.handler.codec.socksx.v5.SocksV5CmdType;
|
import io.netty.handler.codec.socksx.v5.Socks5CmdType;
|
||||||
|
|
||||||
@ChannelHandler.Sharable
|
@ChannelHandler.Sharable
|
||||||
public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksRequest> {
|
public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksRequest> {
|
||||||
|
|
||||||
|
public static final SocksServerHandler INSTANCE = new SocksServerHandler();
|
||||||
|
|
||||||
|
private SocksServerHandler() { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead0(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception {
|
public void channelRead0(ChannelHandlerContext ctx, SocksRequest socksRequest) throws Exception {
|
||||||
switch (socksRequest.protocolVersion()) {
|
switch (socksRequest.protocolVersion()) {
|
||||||
case SOCKS4a:
|
case SOCKS4a:
|
||||||
SocksV4CmdRequest socksV4CmdRequest = (SocksV4CmdRequest) socksRequest;
|
Socks4CmdRequest socksV4CmdRequest = (Socks4CmdRequest) socksRequest;
|
||||||
if (socksV4CmdRequest.cmdType() == SocksV4CmdType.CONNECT) {
|
if (socksV4CmdRequest.cmdType() == Socks4CmdType.CONNECT) {
|
||||||
ctx.pipeline().addLast(new SocksServerConnectHandler());
|
ctx.pipeline().addLast(new SocksServerConnectHandler());
|
||||||
ctx.pipeline().remove(this);
|
ctx.pipeline().remove(this);
|
||||||
ctx.fireChannelRead(socksRequest);
|
ctx.fireChannelRead(socksRequest);
|
||||||
@ -47,22 +51,22 @@ public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksR
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SOCKS5:
|
case SOCKS5:
|
||||||
switch (((SocksV5Request) socksRequest).requestType()) {
|
switch (((Socks5Request) socksRequest).requestType()) {
|
||||||
case INIT: {
|
case INIT: {
|
||||||
// auth support example
|
// auth support example
|
||||||
//ctx.pipeline().addFirst(new SocksV5AuthRequestDecoder());
|
//ctx.pipeline().addFirst(new SocksV5AuthRequestDecoder());
|
||||||
//ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.AUTH_PASSWORD));
|
//ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.AUTH_PASSWORD));
|
||||||
ctx.pipeline().addFirst(new SocksV5CmdRequestDecoder());
|
ctx.pipeline().addFirst(new Socks5CmdRequestDecoder());
|
||||||
ctx.write(new SocksV5InitResponse(SocksV5AuthScheme.NO_AUTH));
|
ctx.write(new Socks5InitResponse(Socks5AuthScheme.NO_AUTH));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AUTH:
|
case AUTH:
|
||||||
ctx.pipeline().addFirst(new SocksV5CmdRequestDecoder());
|
ctx.pipeline().addFirst(new Socks5CmdRequestDecoder());
|
||||||
ctx.write(new SocksV5AuthResponse(SocksV5AuthStatus.SUCCESS));
|
ctx.write(new Socks5AuthResponse(Socks5AuthStatus.SUCCESS));
|
||||||
break;
|
break;
|
||||||
case CMD:
|
case CMD:
|
||||||
SocksV5CmdRequest socksV5CmdRequest = (SocksV5CmdRequest) socksRequest;
|
Socks5CmdRequest socks5CmdRequest = (Socks5CmdRequest) socksRequest;
|
||||||
if (socksV5CmdRequest.cmdType() == SocksV5CmdType.CONNECT) {
|
if (socks5CmdRequest.cmdType() == Socks5CmdType.CONNECT) {
|
||||||
ctx.pipeline().addLast(new SocksServerConnectHandler());
|
ctx.pipeline().addLast(new SocksServerConnectHandler());
|
||||||
ctx.pipeline().remove(this);
|
ctx.pipeline().remove(this);
|
||||||
ctx.fireChannelRead(socksRequest);
|
ctx.fireChannelRead(socksRequest);
|
||||||
@ -91,12 +95,4 @@ public final class SocksServerHandler extends SimpleChannelInboundHandler<SocksR
|
|||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
SocksServerUtils.closeOnFlush(ctx.channel());
|
SocksServerUtils.closeOnFlush(ctx.channel());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SocksServerHandlerHolder {
|
|
||||||
public static final SocksServerHandler HOLDER_INSTANCE = new SocksServerHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SocksServerHandler getInstance() {
|
|
||||||
return SocksServerHandlerHolder.HOLDER_INSTANCE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user