1 4 package com.tc.net.protocol.transport; 5 6 import com.tc.bytes.TCByteBuffer; 7 import com.tc.net.protocol.AbstractTCNetworkHeader; 8 import com.tc.net.protocol.TCNetworkMessage; 9 import com.tc.net.protocol.delivery.OOOProtocolMessage; 10 import com.tc.net.protocol.tcm.TCMessage; 11 import com.tc.util.Conversion; 12 13 41 42 public class WireProtocolHeader extends AbstractTCNetworkHeader { 43 public static final byte VERSION_1 = 1; 44 public static final byte[] VALID_VERSIONS = new byte[] { VERSION_1 }; 45 46 public static final short DEFAULT_TTL = 64; 47 48 public static final short PROTOCOL_UNKNOWN = 0; 49 public static final short PROTOCOL_TCM = 1; 50 public static final short PROTOCOL_TRANSPORT_HANDSHAKE = 2; 51 public static final short PROTOCOL_OOOP = 3; 52 53 private static final int MAGIC_NUM = 0xAAAAAAAA; 54 55 public static final short[] VALID_PROTOCOLS = new short[] { PROTOCOL_TCM, PROTOCOL_TRANSPORT_HANDSHAKE, 56 PROTOCOL_OOOP }; 57 58 static final short MAX_LENGTH = 15 * 4; 60 61 static final short MIN_LENGTH = 7 * 4; 63 64 public static short getProtocolForMessageClass(TCNetworkMessage msg) { 65 if (msg instanceof TCMessage) { 67 return PROTOCOL_TCM; 68 } else if (msg instanceof OOOProtocolMessage) { return PROTOCOL_OOOP; } 69 70 throw new AssertionError ("Unknown protocol"); 71 } 72 73 public WireProtocolHeader() { 74 super(MIN_LENGTH, MAX_LENGTH); 75 76 setMagicNum(MAGIC_NUM); 77 setVersion(VERSION_1); 78 setHeaderLength((byte) (MIN_LENGTH / 4)); 79 setTimeToLive(DEFAULT_TTL); 80 setTypeOfService(TypeOfService.DEFAULT_TOS.getByteValue()); 81 } 82 83 public WireProtocolHeader(TCByteBuffer buffer) { 84 super(buffer, MIN_LENGTH, MAX_LENGTH); 85 } 86 87 private void setMagicNum(int magic_num2) { 88 data.putInt(4, MAGIC_NUM); 89 } 90 91 public void setVersion(byte version) { 92 if ((version <= 0) || (version > 15)) { throw new IllegalArgumentException ("invalid version: " + version); } 93 94 set4BitValue(0, true, version); 95 } 96 97 protected void setHeaderLength(short length) { 98 if ((length < 6) || (length > 15)) { throw new IllegalArgumentException ("Header length must in range 6-15"); } 99 100 set4BitValue(0, false, (byte) length); 101 } 102 103 public void setTypeOfService(short tos) { 104 data.putUbyte(1, tos); 105 } 106 107 public void setTimeToLive(short ttl) { 108 data.putUbyte(2, ttl); 109 } 110 111 public void setProtocol(short protocol) { 112 data.putUbyte(3, protocol); 113 } 114 115 public void setTotalPacketLength(int length) { 116 data.putInt(8, length); 117 } 118 119 public void setSourceAddress(byte[] srcAddr) { 120 data.put(16, srcAddr, 0, 4); 121 } 122 123 public void setDestinationAddress(byte[] destAddr) { 124 data.put(20, destAddr, 0, 4); 125 } 126 127 public void setSourcePort(int srcPort) { 128 data.putUshort(24, srcPort); 129 } 130 131 public void setDestinationPort(int dstPort) { 132 data.putUshort(26, dstPort); 133 } 134 135 public int getMagicNum() { 136 return data.getInt(4); 137 } 138 139 public byte getVersion() { 140 return get4BitValue(0, true); 141 } 142 143 public byte getHeaderLength() { 144 return get4BitValue(0, false); 145 } 146 147 public short getTypeOfService() { 148 return data.getUbyte(1); 149 } 150 151 public short getTimeToLive() { 152 return data.getUbyte(2); 153 } 154 155 public short getProtocol() { 156 return data.getUbyte(3); 157 } 158 159 public int getTotalPacketLength() { 160 return data.getInt(8); 161 } 162 163 public long getChecksum() { 164 return data.getUint(12); 165 } 166 167 public byte[] getSourceAddress() { 168 return getBytes(16, 4); 169 } 170 171 public byte[] getDestinationAddress() { 172 return getBytes(20, 4); 173 } 174 175 public int getSourcePort() { 176 return data.getUshort(24); 177 } 178 179 public int getDestinationPort() { 180 return data.getUshort(26); 181 } 182 183 public void computeChecksum() { 184 computeAdler32Checksum(12, true); 185 } 186 187 public boolean isChecksumValid() { 188 return getChecksum() == computeAdler32Checksum(12, false); 189 } 190 191 public void validate() throws WireProtocolHeaderFormatException { 192 int magic = getMagicNum(); 194 if (magic != MAGIC_NUM) { throw new WireProtocolHeaderFormatException("Invalid magic number: " + magic + " != " 195 + MAGIC_NUM); } 196 197 boolean validVersion = false; 199 byte version = getVersion(); 200 201 for (int i = 0; i < VALID_VERSIONS.length; i++) { 202 if (version == VALID_VERSIONS[i]) { 203 validVersion = true; 204 break; 205 } 206 } 207 208 if (!validVersion) { throw new WireProtocolHeaderFormatException("Bad Version: " + Conversion.byte2uint(version)); } 209 210 212 int ttl = getTimeToLive(); 214 if (0 == ttl) { throw new WireProtocolHeaderFormatException("TTL byte cannot be equal to zero"); } 215 216 boolean validProtocol = false; 218 short protocol = getProtocol(); 219 220 for (int i = 0; i < VALID_PROTOCOLS.length; i++) { 221 if (protocol == VALID_PROTOCOLS[i]) { 222 validProtocol = true; 223 break; 224 } 225 } 226 227 if (!validProtocol) { throw new WireProtocolHeaderFormatException("Bad Protocol byte: " + protocol); } 228 229 int totalLength = getTotalPacketLength(); 231 232 if (totalLength < MIN_LENGTH) { throw new WireProtocolHeaderFormatException( 233 "Total length (" 234 + totalLength 235 + ") can not be less than minimum header size (" 236 + MIN_LENGTH 237 + ")"); } 238 239 if (totalLength < getHeaderByteLength()) { throw new WireProtocolHeaderFormatException( 240 "Total length (" 241 + totalLength 242 + ") can not be less than actual header length (" 243 + getHeaderByteLength() 244 + ")"); } 245 246 if (!isChecksumValid()) { throw new WireProtocolHeaderFormatException("Invalid Checksum"); } 248 249 if (getSourcePort() == 0) { throw new WireProtocolHeaderFormatException("Source port cannot be zero"); } 250 251 if (getDestinationPort() == 0) { throw new WireProtocolHeaderFormatException("Destination port cannot be zero"); } 252 253 259 } 261 262 public String toString() { 263 StringBuffer buf = new StringBuffer (); 264 buf.append("Version: ").append(Conversion.byte2uint(getVersion())).append(", "); 265 buf.append("Header Length: ").append(Conversion.byte2uint(getHeaderLength())).append(", "); 266 buf.append("TOS: ").append(getTypeOfService()).append(", "); 267 buf.append("TTL: ").append(getTimeToLive()).append(", "); 268 buf.append("Protocol: ").append(getProtocolString()); 269 buf.append("\n"); 270 buf.append("Total Packet Length: ").append(getTotalPacketLength()).append("\n"); 271 buf.append("Adler32 Checksum: ").append(getChecksum()).append(" (valid: ").append(isChecksumValid()).append(")\n"); 272 buf.append("Source Addresss: "); 273 274 byte src[] = getSourceAddress(); 275 byte dest[] = getDestinationAddress(); 276 277 for (int i = 0; i < src.length; i++) { 278 buf.append(Conversion.byte2uint(src[i])); 279 if (i != (src.length - 1)) { 280 buf.append("."); 281 } 282 } 283 buf.append("\n"); 284 285 buf.append("Destination Addresss: "); 286 for (int i = 0; i < dest.length; i++) { 287 buf.append(Conversion.byte2uint(dest[i])); 288 if (i != (dest.length - 1)) { 289 buf.append("."); 290 } 291 } 292 buf.append("\n"); 293 294 buf.append("Source Port: ").append(getSourcePort()); 295 buf.append(", Destination Port: ").append(getDestinationPort()); 296 buf.append("\n"); 297 298 String errMsg = "no message"; 299 boolean valid = true; 300 try { 301 validate(); 302 } catch (WireProtocolHeaderFormatException e) { 303 errMsg = e.getMessage(); 304 valid = false; 305 } 306 buf.append("Header Validity: ").append(valid).append(" (").append(errMsg).append(")\n"); 307 308 310 return buf.toString(); 311 } 312 313 private String getProtocolString() { 314 final short protocol = getProtocol(); 315 switch (protocol) { 316 case PROTOCOL_TCM: { 317 return "TCM"; 318 } 319 case PROTOCOL_OOOP: { 320 return "OOOP"; 321 } 322 case PROTOCOL_TRANSPORT_HANDSHAKE: { 323 return "TRANSPORT HANDSHAKE"; 324 } 325 default: { 326 return "UNKNOWN (" + protocol + ")"; 327 } 328 } 329 } 330 331 public int getMaxByteLength() { 332 return WireProtocolHeader.MAX_LENGTH; 333 } 334 335 public int getMinByteLength() { 336 return WireProtocolHeader.MIN_LENGTH; 337 } 338 339 public int getHeaderByteLength() { 340 return 4 * getHeaderLength(); 341 } 342 343 public boolean isTransportHandshakeMessage() { 344 return getProtocol() == PROTOCOL_TRANSPORT_HANDSHAKE; 345 } 346 } | Popular Tags |