/* * Copyright 2015-2025 the original author or authors. * * Licensed 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 sockslib.server.msg; import sockslib.common.AddressType; import sockslib.common.NotImplementException; import sockslib.utils.SocksUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.InetAddress; import java.net.UnknownHostException; /** * The class <code>CommandResponseMessage</code> represents a command response message. * * @author Youchao Feng * @version 1.0 * @date Apr 6, 2015 11:10:25 AM */ public class CommandResponseMessage implements WritableMessage { /** * Logger that subclasses also can use. */ protected static final Logger logger = LoggerFactory.getLogger(CommandResponseMessage.class); private int version = 5; /** * The reserved field. */ private int reserved = 0x00; /** * Address type. */ private int addressType = AddressType.IPV4; /** * Bind address. */ private InetAddress bindAddress; /** * Bind port. */ private int bindPort; /** * Rely from SOCKS server. */ private ServerReply reply; /** * Constructs a {@link CommandResponseMessage} by {@link ServerReply}. * * @param reply Reply from server. */ public CommandResponseMessage(ServerReply reply) { byte[] defaultAddress = {0, 0, 0, 0}; this.reply = reply; try { bindAddress = InetAddress.getByAddress(defaultAddress); addressType = 0x01; } catch (UnknownHostException e) { logger.error(e.getMessage(), e); } } /** * Constructs a {@link CommandResponseMessage}. * * @param version Version * @param reply Sever reply. * @param bindAddress Bind IP address. * @param bindPort Bind port. */ public CommandResponseMessage(int version, ServerReply reply, InetAddress bindAddress, int bindPort) { this.version = version; this.reply = reply; this.bindAddress = bindAddress; this.bindPort = bindPort; if (bindAddress.getAddress().length == 4) { addressType = 0x01; } else { addressType = 0x04; } } @Override public byte[] getBytes() { byte[] bytes = null; switch (addressType) { case AddressType.IPV4: bytes = new byte[10]; for (int i = 0; i < bindAddress.getAddress().length; i++) { bytes[i + 4] = bindAddress.getAddress()[i]; } bytes[8] = SocksUtil.getFirstByteFromInt(bindPort); bytes[9] = SocksUtil.getSecondByteFromInt(bindPort); break; case AddressType.IPV6: bytes = new byte[22]; for (int i = 0; i < bindAddress.getAddress().length; i++) { bytes[i + 4] = bindAddress.getAddress()[i]; } bytes[20] = SocksUtil.getFirstByteFromInt(bindPort); bytes[21] = SocksUtil.getSecondByteFromInt(bindPort); break; case AddressType.DOMAIN_NAME: throw new NotImplementException(); default: break; } bytes[0] = (byte) version; bytes[1] = reply.getValue(); bytes[2] = (byte) reserved; bytes[3] = (byte) addressType; return bytes; } @Override public int getLength() { return getBytes().length; } /** * Returns version. * * @return Version. */ public int getVersion() { return version; } /** * Sets version. * * @param version Version. */ public void setVersion(int version) { this.version = version; } /** * Returns address type. * * @return Address type. */ public int getAddressType() { return addressType; } /** * Sets address type. * * @param addressType Address type. */ public void setAddressType(int addressType) { this.addressType = addressType; } /** * Returns bind address. * * @return Bind address. */ public InetAddress getBindAddress() { return bindAddress; } /** * Sets bind address. * * @param bindAddress Bind address. */ public void setBindAddress(InetAddress bindAddress) { this.bindAddress = bindAddress; } /** * Returns bind port. * * @return Bind port. */ public int getBindPort() { return bindPort; } /** * Sets bind port. * * @param bindPort Bind port. */ public void setBindPort(int bindPort) { this.bindPort = bindPort; } /** * Returns the reply of SOCKS server. * * @return SOCKS server's reply. */ public ServerReply getReply() { return reply; } /** * Sets SOCKS server's reply. * * @param reply Reply of the SOCKS server. */ public void setReply(ServerReply reply) { this.reply = reply; } }