View Javadoc
1   /*
2    * Copyright 2016 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  
17  package io.netty.handler.codec.haproxy;
18  
19  import io.netty.buffer.ByteBuf;
20  import io.netty.buffer.DefaultByteBufHolder;
21  import io.netty.util.internal.StringUtil;
22  
23  import static io.netty.util.internal.ObjectUtil.*;
24  
25  /**
26   * A Type-Length Value (TLV vector) that can be added to the PROXY protocol
27   * to include additional information like SSL information.
28   *
29   * @see HAProxySSLTLV
30   */
31  public class HAProxyTLV extends DefaultByteBufHolder {
32  
33      private final Type type;
34      private final byte typeByteValue;
35  
36      /**
37       * The size of this tlv in bytes.
38       * @return the number of bytes.
39       */
40      int totalNumBytes() {
41          return 3 + contentNumBytes(); // type(1) + length(2) + content
42      }
43  
44      int contentNumBytes() {
45          return content().readableBytes();
46      }
47  
48      /**
49       * The registered types a TLV can have regarding the PROXY protocol 1.5 spec
50       */
51      public enum Type {
52          PP2_TYPE_ALPN,
53          PP2_TYPE_AUTHORITY,
54          PP2_TYPE_SSL,
55          PP2_TYPE_SSL_VERSION,
56          PP2_TYPE_SSL_CN,
57          PP2_TYPE_NETNS,
58          /**
59           * A TLV type that is not officially defined in the spec. May be used for nonstandard TLVs
60           */
61          OTHER;
62  
63          /**
64           * Returns the {@link Type} for a specific byte value as defined in the PROXY protocol 1.5 spec
65           * <p>
66           * If the byte value is not an official one, it will return {@link Type#OTHER}.
67           *
68           * @param byteValue the byte for a type
69           *
70           * @return the {@link Type} of a TLV
71           */
72          public static Type typeForByteValue(byte byteValue) {
73              switch (byteValue) {
74              case 0x01:
75                  return PP2_TYPE_ALPN;
76              case 0x02:
77                  return PP2_TYPE_AUTHORITY;
78              case 0x20:
79                  return PP2_TYPE_SSL;
80              case 0x21:
81                  return PP2_TYPE_SSL_VERSION;
82              case 0x22:
83                  return PP2_TYPE_SSL_CN;
84              case 0x30:
85                  return PP2_TYPE_NETNS;
86              default:
87                  return OTHER;
88              }
89          }
90  
91          /**
92           * Returns the byte value for the {@link Type} as defined in the PROXY protocol 1.5 spec.
93           *
94           * @param type the {@link Type}
95           *
96           * @return the byte value of the {@link Type}.
97           */
98          public static byte byteValueForType(Type type) {
99              switch (type) {
100             case PP2_TYPE_ALPN:
101                 return 0x01;
102             case PP2_TYPE_AUTHORITY:
103                 return 0x02;
104             case PP2_TYPE_SSL:
105                 return 0x20;
106             case PP2_TYPE_SSL_VERSION:
107                 return 0x21;
108             case PP2_TYPE_SSL_CN:
109                 return 0x22;
110             case PP2_TYPE_NETNS:
111                 return 0x30;
112             default:
113                 throw new IllegalArgumentException("unknown type: " + type);
114             }
115         }
116     }
117 
118     /**
119      * Creates a new HAProxyTLV
120      *
121      * @param typeByteValue the byteValue of the TLV. This is especially important if non-standard TLVs are used
122      * @param content the raw content of the TLV
123      */
124     public HAProxyTLV(byte typeByteValue, ByteBuf content) {
125         this(Type.typeForByteValue(typeByteValue), typeByteValue, content);
126     }
127 
128     /**
129      * Creates a new HAProxyTLV
130      *
131      * @param type the {@link Type} of the TLV
132      * @param content the raw content of the TLV
133      */
134     public HAProxyTLV(Type type, ByteBuf content) {
135         this(type, Type.byteValueForType(type), content);
136     }
137 
138     /**
139      * Creates a new HAProxyTLV
140      *
141      * @param type the {@link Type} of the TLV
142      * @param typeByteValue the byteValue of the TLV. This is especially important if non-standard TLVs are used
143      * @param content the raw content of the TLV
144      */
145     HAProxyTLV(final Type type, final byte typeByteValue, final ByteBuf content) {
146         super(content);
147         this.type = checkNotNull(type, "type");
148         this.typeByteValue = typeByteValue;
149     }
150 
151     /**
152      * Returns the {@link Type} of this TLV
153      */
154     public Type type() {
155         return type;
156     }
157 
158     /**
159      * Returns the type of the TLV as byte
160      */
161     public byte typeByteValue() {
162         return typeByteValue;
163     }
164 
165     @Override
166     public HAProxyTLV copy() {
167         return replace(content().copy());
168     }
169 
170     @Override
171     public HAProxyTLV duplicate() {
172         return replace(content().duplicate());
173     }
174 
175     @Override
176     public HAProxyTLV retainedDuplicate() {
177         return replace(content().retainedDuplicate());
178     }
179 
180     @Override
181     public HAProxyTLV replace(ByteBuf content) {
182         return new HAProxyTLV(type, typeByteValue, content);
183     }
184 
185     @Override
186     public HAProxyTLV retain() {
187         super.retain();
188         return this;
189     }
190 
191     @Override
192     public HAProxyTLV retain(int increment) {
193         super.retain(increment);
194         return this;
195     }
196 
197     @Override
198     public HAProxyTLV touch() {
199         super.touch();
200         return this;
201     }
202 
203     @Override
204     public HAProxyTLV touch(Object hint) {
205         super.touch(hint);
206         return this;
207     }
208 
209     @Override
210     public String toString() {
211         return StringUtil.simpleClassName(this) +
212                "(type: " + type() +
213                ", typeByteValue: " + typeByteValue() +
214                ", content: " + contentToString() + ')';
215     }
216 }