1 /* 2 * Conditions Of Use 3 * 4 * This software was developed by employees of the National Institute of 5 * Standards and Technology (NIST), an agency of the Federal Government. 6 * Pursuant to title 15 Untied States Code Section 105, works of NIST 7 * employees are not subject to copyright protection in the United States 8 * and are considered to be in the public domain. As a result, a formal 9 * license is not needed to use the software. 10 * 11 * This software is provided by NIST as a service and is expressly 12 * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15 * AND DATA ACCURACY. NIST does not warrant or make any representations 16 * regarding the use of the software or the results thereof, including but 17 * not limited to the correctness, accuracy, reliability or usefulness of 18 * the software. 19 * 20 * Permission to use this software is contingent upon your acceptance 21 * of the terms of this agreement 22 * 23 * . 24 * 25 */ 26 /******************************************************************************* 27 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 28 *******************************************************************************/ 29 package gov.nist.javax.sip.header; 30 31 import gov.nist.core.Host; 32 import gov.nist.core.HostPort; 33 import gov.nist.core.NameValue; 34 import gov.nist.core.NameValueList; 35 import gov.nist.javax.sip.stack.HopImpl; 36 37 import javax.sip.InvalidArgumentException; 38 import javax.sip.address.Hop; 39 import javax.sip.header.ViaHeader; 40 import java.text.ParseException; 41 42 /** 43 * Via SIPHeader (these are strung together in a ViaList). 44 * 45 * @see ViaList 46 * 47 * @version 1.2 $Revision: 1.17 $ $Date: 2009/10/18 13:46:33 $ 48 * 49 * @author M. Ranganathan <br/> 50 * 51 * 52 * 53 */ 54 public class Via 55 extends ParametersHeader 56 implements javax.sip.header.ViaHeader, ViaHeaderExt { 57 58 /** 59 * Comment for <code>serialVersionUID</code> 60 */ 61 private static final long serialVersionUID = 5281728373401351378L; 62 63 /** The branch parameter is included by every forking proxy. 64 */ 65 public static final String BRANCH = ParameterNames.BRANCH; 66 67 /** The "received" parameter is added only for receiver-added Via Fields. 68 */ 69 public static final String RECEIVED = ParameterNames.RECEIVED; 70 71 /** The "maddr" paramter is designating the multicast address. 72 */ 73 public static final String MADDR = ParameterNames.MADDR; 74 75 /** The "TTL" parameter is designating the time-to-live value. 76 */ 77 public static final String TTL = ParameterNames.TTL; 78 79 /** The RPORT parameter. 80 */ 81 public static final String RPORT = ParameterNames.RPORT; 82 83 /** sentProtocol field. 84 */ 85 protected Protocol sentProtocol; 86 87 /** sentBy field. 88 */ 89 protected HostPort sentBy; 90 91 /** 92 * comment field 93 * 94 * JvB note: RFC3261 does not allow a comment to appear in Via headers, and this 95 * is not accessible through the API. Suggest removal 96 */ 97 protected String comment; 98 99 private boolean rPortFlag = false; 100 101 /** Default constructor 102 */ Via()103 public Via() { 104 super(NAME); 105 sentProtocol = new Protocol(); 106 } 107 equals(Object other)108 public boolean equals(Object other) { 109 110 if (other==this) return true; 111 112 if (other instanceof ViaHeader) { 113 final ViaHeader o = (ViaHeader) other; 114 return getProtocol().equalsIgnoreCase( o.getProtocol() ) 115 && getTransport().equalsIgnoreCase( o.getTransport() ) 116 && getHost().equalsIgnoreCase( o.getHost() ) 117 && getPort() == o.getPort() 118 && equalParameters( o ); 119 } 120 return false; 121 } 122 123 124 /** get the Protocol Version 125 * @return String 126 */ getProtocolVersion()127 public String getProtocolVersion() { 128 if (sentProtocol == null) 129 return null; 130 else 131 return sentProtocol.getProtocolVersion(); 132 } 133 134 /** 135 * Accessor for the sentProtocol field. 136 * @return Protocol field 137 */ getSentProtocol()138 public Protocol getSentProtocol() { 139 140 return sentProtocol; 141 } 142 143 /** 144 * Accessor for the sentBy field 145 *@return SentBy field 146 */ getSentBy()147 public HostPort getSentBy() { 148 return sentBy; 149 } 150 151 /** 152 * Get the host, port and transport as a Hop. This is 153 * useful for the stack to avoid duplication of code. 154 * 155 */ getHop()156 public Hop getHop() { 157 HopImpl hop = new HopImpl(sentBy.getHost().getHostname(), 158 sentBy.getPort(),sentProtocol.getTransport()); 159 return hop; 160 } 161 162 /** 163 * Accessor for the parameters field 164 * @return parameters field 165 */ getViaParms()166 public NameValueList getViaParms() { 167 return parameters; 168 } 169 170 /** 171 * Accessor for the comment field. 172 * @return comment field. 173 * @deprecated RFC 2543 support feature. 174 */ getComment()175 public String getComment() { 176 return comment; 177 } 178 179 180 181 /** port of the Via Header. 182 * @return true if Port exists. 183 */ hasPort()184 public boolean hasPort() { 185 return (getSentBy()).hasPort(); 186 } 187 188 /** comment of the Via Header. 189 * 190 * @return false if comment does not exist and true otherwise. 191 */ hasComment()192 public boolean hasComment() { 193 return comment != null; 194 } 195 196 /** remove the port. 197 */ removePort()198 public void removePort() { 199 sentBy.removePort(); 200 } 201 202 /** remove the comment field. 203 */ removeComment()204 public void removeComment() { 205 comment = null; 206 } 207 208 /** set the Protocol Version 209 * @param protocolVersion String to set 210 */ setProtocolVersion(String protocolVersion)211 public void setProtocolVersion(String protocolVersion) { 212 if (sentProtocol == null) 213 sentProtocol = new Protocol(); 214 sentProtocol.setProtocolVersion(protocolVersion); 215 } 216 217 /** set the Host of the Via Header 218 * @param host String to set 219 */ setHost(Host host)220 public void setHost(Host host) { 221 if (sentBy == null) { 222 sentBy = new HostPort(); 223 } 224 sentBy.setHost(host); 225 } 226 227 /** 228 * Set the sentProtocol member 229 * @param s Protocol to set. 230 */ setSentProtocol(Protocol s)231 public void setSentProtocol(Protocol s) { 232 sentProtocol = s; 233 } 234 235 /** 236 * Set the sentBy member 237 * @param s HostPort to set. 238 */ setSentBy(HostPort s)239 public void setSentBy(HostPort s) { 240 sentBy = s; 241 } 242 243 /** 244 * Set the comment member 245 * @param c String to set. 246 * @deprecated This is an RFC 2543 feature. 247 */ setComment(String c)248 public void setComment(String c) { 249 comment = c; 250 } 251 252 /** Encode the body of this header (the stuff that follows headerName). 253 * A.K.A headerValue. 254 */ encodeBody()255 protected String encodeBody() { 256 return encodeBody(new StringBuffer()).toString(); 257 } 258 encodeBody(StringBuffer buffer)259 protected StringBuffer encodeBody(StringBuffer buffer) { 260 sentProtocol.encode(buffer); 261 buffer.append(SP); 262 sentBy.encode(buffer); 263 if (!parameters.isEmpty()) { 264 buffer.append(SEMICOLON); 265 parameters.encode(buffer); 266 } 267 if (comment != null) { 268 buffer.append(SP).append(LPAREN).append(comment).append(RPAREN); 269 } 270 if (rPortFlag) buffer.append(";rport"); 271 return buffer; 272 } 273 274 /** 275 * Set the host part of this ViaHeader to the newly supplied <code>host</code> 276 * parameter. 277 * 278 * @throws ParseException which signals that an error has been reached 279 * unexpectedly while parsing the host value. 280 */ setHost(String host)281 public void setHost(String host) throws ParseException { 282 if (sentBy == null) 283 sentBy = new HostPort(); 284 try { 285 Host h = new Host(host); 286 sentBy.setHost(h); 287 } catch (Exception e) { 288 throw new NullPointerException(" host parameter is null"); 289 } 290 } 291 292 /** 293 * Returns the host part of this ViaHeader. 294 * 295 * @return the string value of the host 296 */ getHost()297 public String getHost() { 298 if (sentBy == null) 299 return null; 300 else { 301 Host host = sentBy.getHost(); 302 if (host == null) 303 return null; 304 else 305 return host.getHostname(); 306 } 307 } 308 309 /** 310 * Set the port part of this ViaHeader to the newly supplied <code>port</code> 311 * parameter. 312 * 313 * @param port - the Integer.valueOf value of the port of this ViaHeader 314 */ setPort(int port)315 public void setPort(int port) throws InvalidArgumentException { 316 317 if ( port!=-1 && (port<1 || port>65535)) { 318 throw new InvalidArgumentException( "Port value out of range -1, [1..65535]" ); 319 } 320 321 if (sentBy == null) 322 sentBy = new HostPort(); 323 sentBy.setPort(port); 324 } 325 326 /** 327 * Set the RPort flag parameter 328 */ setRPort()329 public void setRPort(){ 330 rPortFlag = true; 331 } 332 333 /** 334 * Returns the port part of this ViaHeader. 335 * 336 * @return the integer value of the port 337 */ getPort()338 public int getPort() { 339 if (sentBy == null) 340 return -1; 341 return sentBy.getPort(); 342 } 343 344 345 /** 346 * Return the rport parameter. 347 * 348 *@return the rport parameter or -1. 349 */ getRPort()350 public int getRPort() { 351 String strRport = getParameter(ParameterNames.RPORT); 352 if (strRport != null && ! strRport.equals("")) 353 return Integer.valueOf(strRport).intValue(); 354 else 355 return -1; 356 } 357 358 359 /** 360 * Returns the value of the transport parameter. 361 * 362 * @return the string value of the transport paramter of the ViaHeader 363 */ getTransport()364 public String getTransport() { 365 if (sentProtocol == null) 366 return null; 367 return sentProtocol.getTransport(); 368 } 369 370 /** 371 * Sets the value of the transport. This parameter specifies 372 * which transport protocol to use for sending requests and responses to 373 * this entity. The following values are defined: "udp", "tcp", "sctp", 374 * "tls", but other values may be used also. 375 * 376 * @param transport - new value for the transport parameter 377 * @throws ParseException which signals that an error has been reached 378 * unexpectedly while parsing the transport value. 379 */ setTransport(String transport)380 public void setTransport(String transport) throws ParseException { 381 if (transport == null) 382 throw new NullPointerException( 383 "JAIN-SIP Exception, " 384 + "Via, setTransport(), the transport parameter is null."); 385 if (sentProtocol == null) 386 sentProtocol = new Protocol(); 387 sentProtocol.setTransport(transport); 388 } 389 390 /** 391 * Returns the value of the protocol used. 392 * 393 * @return the string value of the protocol paramter of the ViaHeader 394 */ getProtocol()395 public String getProtocol() { 396 if (sentProtocol == null) 397 return null; 398 return sentProtocol.getProtocol();// JvB: Return name ~and~ version 399 } 400 401 /** 402 * Sets the value of the protocol parameter. This parameter specifies 403 * which protocol is used, for example "SIP/2.0". 404 * 405 * @param protocol - new value for the protocol parameter 406 * @throws ParseException which signals that an error has been reached 407 * unexpectedly while parsing the protocol value. 408 */ setProtocol(String protocol)409 public void setProtocol(String protocol) throws ParseException { 410 if (protocol == null) 411 throw new NullPointerException( 412 "JAIN-SIP Exception, " 413 + "Via, setProtocol(), the protocol parameter is null."); 414 415 if (sentProtocol == null) 416 sentProtocol = new Protocol(); 417 418 sentProtocol.setProtocol(protocol); 419 } 420 421 /** 422 * Returns the value of the ttl parameter, or -1 if this is not set. 423 * 424 * @return the integer value of the <code>ttl</code> parameter 425 */ getTTL()426 public int getTTL() { 427 int ttl = getParameterAsInt(ParameterNames.TTL); 428 return ttl; 429 } 430 431 /** 432 * Sets the value of the ttl parameter. The ttl parameter specifies the 433 * time-to-live value when packets are sent using UDP multicast. 434 * 435 * @param ttl - new value of the ttl parameter 436 * @throws InvalidArgumentException if supplied value is less than zero or 437 * greater than 255, excluding -1 the default not set value. 438 */ setTTL(int ttl)439 public void setTTL(int ttl) throws InvalidArgumentException { 440 if (ttl < 0 && ttl != -1) 441 throw new InvalidArgumentException( 442 "JAIN-SIP Exception" 443 + ", Via, setTTL(), the ttl parameter is < 0"); 444 setParameter(new NameValue(ParameterNames.TTL, Integer.valueOf(ttl))); 445 } 446 447 /** 448 * Returns the value of the <code>maddr</code> parameter, or null if this 449 * is not set. 450 * 451 * @return the string value of the maddr parameter 452 */ getMAddr()453 public String getMAddr() { 454 return getParameter(ParameterNames.MADDR); 455 } 456 457 /** 458 * Sets the value of the <code>maddr</code> parameter of this ViaHeader. The 459 * maddr parameter indicates the server address to be contacted for this 460 * user, overriding any address derived from the host field. 461 * 462 * @param mAddr new value of the <code>maddr</code> parameter 463 * @throws ParseException which signals that an error has been reached 464 * unexpectedly while parsing the mAddr value. 465 */ setMAddr(String mAddr)466 public void setMAddr(String mAddr) throws ParseException { 467 if (mAddr == null) 468 throw new NullPointerException( 469 "JAIN-SIP Exception, " 470 + "Via, setMAddr(), the mAddr parameter is null."); 471 472 Host host = new Host(); 473 host.setAddress(mAddr); 474 NameValue nameValue = new NameValue(ParameterNames.MADDR, host); 475 setParameter(nameValue); 476 477 } 478 479 /** 480 * Gets the received paramater of the ViaHeader. Returns null if received 481 * does not exist. 482 * 483 * @return the string received value of ViaHeader 484 */ getReceived()485 public String getReceived() { 486 return getParameter(ParameterNames.RECEIVED); 487 } 488 489 /** 490 * Sets the received parameter of ViaHeader. 491 * 492 * @param received - the newly supplied received parameter. 493 * @throws ParseException which signals that an error has been reached 494 * unexpectedly while parsing the received value. 495 */ setReceived(String received)496 public void setReceived(String received) throws ParseException { 497 if (received == null) 498 throw new NullPointerException( 499 "JAIN-SIP Exception, " 500 + "Via, setReceived(), the received parameter is null."); 501 502 setParameter(ParameterNames.RECEIVED, received); 503 504 } 505 506 /** 507 * Gets the branch paramater of the ViaHeader. Returns null if branch 508 * does not exist. 509 * 510 * @return the string branch value of ViaHeader 511 */ getBranch()512 public String getBranch() { 513 return getParameter(ParameterNames.BRANCH); 514 } 515 516 /** 517 * Sets the branch parameter of the ViaHeader to the newly supplied 518 * branch value. 519 * 520 * @param branch - the new string branch parmameter of the ViaHeader. 521 * @throws ParseException which signals that an error has been reached 522 * unexpectedly while parsing the branch value. 523 */ setBranch(String branch)524 public void setBranch(String branch) throws ParseException { 525 if (branch == null || branch.length()==0) 526 throw new NullPointerException( 527 "JAIN-SIP Exception, " 528 + "Via, setBranch(), the branch parameter is null or length 0."); 529 530 setParameter(ParameterNames.BRANCH, branch); 531 } 532 clone()533 public Object clone() { 534 Via retval = (Via) super.clone(); 535 if (this.sentProtocol != null) 536 retval.sentProtocol = (Protocol) this.sentProtocol.clone(); 537 if (this.sentBy != null) 538 retval.sentBy = (HostPort) this.sentBy.clone(); 539 if ( this.getRPort() != -1) 540 retval.setParameter(RPORT,this.getRPort()); 541 return retval; 542 } 543 544 /* 545 * (non-Javadoc) 546 * @see gov.nist.javax.sip.header.ViaHeaderExt#getSentByField() 547 */ getSentByField()548 public String getSentByField() { 549 if(sentBy != null) 550 return sentBy.encode(); 551 return null; 552 } 553 /* 554 * (non-Javadoc) 555 * @see gov.nist.javax.sip.header.ViaHeaderExt#getSentProtocolField() 556 */ getSentProtocolField()557 public String getSentProtocolField() { 558 if(sentProtocol != null) 559 return sentProtocol.encode(); 560 return null; 561 } 562 563 } 564