1 /* 2 * Copyright 2025 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package io.netty.handler.codec.socksx.v5; 17 18 import io.netty.util.internal.ObjectUtil; 19 20 /** 21 * The status of a SOCKS5 private authentication response. 22 * <p> 23 * RFC 1928 reserves method codes 0x80-0xFE for private authentication methods but does not 24 * specify the format of their subnegotiation. This class provides standard status codes 25 * for the private authentication response that follow the pattern established by the 26 * username/password authentication method in RFC 1929. 27 * </p> 28 * 29 * @see <a href="https://www.ietf.org/rfc/rfc1928.txt">RFC 1928 Section 3</a> 30 * @see <a href="https://www.ietf.org/rfc/rfc1929.txt">RFC 1929</a> 31 */ 32 public final class Socks5PrivateAuthStatus implements Comparable<Socks5PrivateAuthStatus> { 33 34 public static final Socks5PrivateAuthStatus SUCCESS = new Socks5PrivateAuthStatus(0x00, "SUCCESS"); 35 public static final Socks5PrivateAuthStatus FAILURE = new Socks5PrivateAuthStatus(0xFF, "FAILURE"); 36 37 /** 38 * Returns the {@link Socks5PrivateAuthStatus} instance that corresponds to the specified byte value. 39 * <p> 40 * This method returns a singleton instance for standard status codes: 41 * <ul> 42 * <li>0x00: {@link #SUCCESS}</li> 43 * <li>0xFF: {@link #FAILURE}</li> 44 * </ul> 45 * For any other values, a new instance is created. 46 * 47 * @param b The byte value of the SOCKS5 private authentication status 48 * @return The corresponding {@link Socks5PrivateAuthStatus} instance 49 */ 50 public static Socks5PrivateAuthStatus valueOf(byte b) { 51 switch (b) { 52 case 0x00: 53 return SUCCESS; 54 case (byte) 0xFF: 55 return FAILURE; 56 } 57 58 return new Socks5PrivateAuthStatus(b); 59 } 60 61 private final byte byteValue; 62 private final String name; 63 private String text; 64 65 private Socks5PrivateAuthStatus(int byteValue) { 66 this(byteValue, "UNKNOWN"); 67 } 68 69 /** 70 * Creates a new SOCKS5 private authentication status. 71 * 72 * @param byteValue The byte value representing the authentication status 73 * (0x00 for success, 0xFF for failure, or custom values) 74 * @param name The descriptive name of this status, must not be null 75 * @throws NullPointerException if the name is null 76 */ 77 public Socks5PrivateAuthStatus(int byteValue, String name) { 78 this.name = ObjectUtil.checkNotNull(name, "name"); 79 this.byteValue = (byte) byteValue; 80 } 81 82 public byte byteValue() { 83 return byteValue; 84 } 85 86 public boolean isSuccess() { 87 return byteValue == 0; 88 } 89 90 @Override 91 public int hashCode() { 92 return byteValue; 93 } 94 95 @Override 96 public boolean equals(Object obj) { 97 if (!(obj instanceof Socks5PrivateAuthStatus)) { 98 return false; 99 } 100 101 return byteValue == ((Socks5PrivateAuthStatus) obj).byteValue; 102 } 103 104 @Override 105 public int compareTo(Socks5PrivateAuthStatus o) { 106 return byteValue - o.byteValue; 107 } 108 109 @Override 110 public String toString() { 111 String text = this.text; 112 if (text == null) { 113 this.text = text = name + '(' + (byteValue & 0xFF) + ')'; 114 } 115 return text; 116 } 117 }