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 package gov.nist.javax.sip.stack; 27 28 import gov.nist.core.Host; 29 import gov.nist.core.HostPort; 30 import gov.nist.core.InternalErrorHandler; 31 import gov.nist.javax.sip.ListeningPointImpl; 32 import gov.nist.javax.sip.header.Via; 33 34 import java.io.IOException; 35 import java.net.InetAddress; 36 import java.text.ParseException; 37 38 import javax.sip.InvalidArgumentException; 39 40 /** 41 * This is the Stack abstraction for the active object that waits for messages 42 * to appear on the wire and processes these messages by calling the 43 * MessageFactory interface to create a ServerRequest or ServerResponse object. 44 * The main job of the message processor is to instantiate message channels for 45 * the given transport. 46 * 47 * @version 1.2 $Revision: 1.18 $ $Date: 2009/10/16 22:58:41 $ 48 * 49 * @author M. Ranganathan <br/> 50 * 51 */ 52 public abstract class MessageProcessor implements Runnable { 53 /** 54 * A string containing the 0.0.0.0 IPv4 ANY address. 55 */ 56 protected static final String IN_ADDR_ANY = "0.0.0.0"; 57 58 /** 59 * A string containing the ::0 IPv6 ANY address. 60 */ 61 protected static final String IN6_ADDR_ANY = "::0"; 62 /** 63 * My Sent by string ( which I use to set the outgoing via header) 64 */ 65 private String sentBy; 66 67 private HostPort sentByHostPort; 68 69 /* 70 * The IP Address that was originally assigned ( Can be ANY ) 71 */ 72 73 private String savedIpAddress; 74 75 /** 76 * The IP address where I am listening. 77 */ 78 private InetAddress ipAddress; 79 80 /** 81 * The port where I am listening 82 */ 83 private int port; 84 85 /** 86 * The transport where I am listening 87 */ 88 protected String transport; 89 90 /** 91 * The Listening Point to which I am assigned. 92 */ 93 private ListeningPointImpl listeningPoint; 94 95 private boolean sentBySet; 96 97 /** 98 * Our stack (that created us). 99 */ 100 protected SIPTransactionStack sipStack; 101 MessageProcessor( String transport )102 protected MessageProcessor( String transport ) { 103 this.transport = transport; 104 } 105 106 /** 107 * Constructor 108 * 109 * @param ipAddress -- ip address where I am listening for incoming requests. 110 * @param port -- port where i am listening for incoming requests. 111 * @param transport -- transport to use for the message processor (UDP/TCP/TLS). 112 */ MessageProcessor( InetAddress ipAddress, int port, String transport, SIPTransactionStack transactionStack )113 protected MessageProcessor( InetAddress ipAddress, int port, String transport, 114 SIPTransactionStack transactionStack ) { 115 this( transport ); 116 this.initialize(ipAddress, port, transactionStack); 117 } 118 119 /** 120 * Initializes this MessageProcessor. Needed for extensions 121 * that use classloading 122 * 123 * @param ipAddress2 124 * @param transactionStack 125 * @param port2 126 */ initialize( InetAddress ipAddress, int port, SIPTransactionStack transactionStack )127 public final void initialize( InetAddress ipAddress, int port, 128 SIPTransactionStack transactionStack ) { 129 130 this.sipStack = transactionStack; 131 this.savedIpAddress = ipAddress.getHostAddress(); 132 this.ipAddress = ipAddress; 133 this.port = port; 134 this.sentByHostPort = new HostPort(); 135 this.sentByHostPort.setHost(new Host(ipAddress.getHostAddress())); 136 this.sentByHostPort.setPort(port); 137 } 138 139 /** 140 * Get the transport string. 141 * 142 * @return A string that indicates the transport. (i.e. "tcp" or "udp") 143 */ getTransport()144 public String getTransport() { 145 return this.transport; 146 } 147 148 /** 149 * Get the port identifier. 150 * 151 * @return the port for this message processor. This is where you receive 152 * messages. 153 */ getPort()154 public int getPort() { 155 return this.port; 156 } 157 158 /** 159 * Get the Via header to assign for this message processor. The topmost via 160 * header of the outoging messages use this. 161 * 162 * @return the ViaHeader to be used by the messages sent via this message processor. 163 */ getViaHeader()164 public Via getViaHeader() { 165 try { 166 Via via = new Via(); 167 if (this.sentByHostPort != null) { 168 via.setSentBy(sentByHostPort); 169 via.setTransport(this.getTransport()); 170 } else { 171 Host host = new Host(); 172 host.setHostname(this.getIpAddress().getHostAddress()); 173 via.setHost(host); 174 via.setPort(this.getPort()); 175 via.setTransport(this.getTransport()); 176 } 177 return via; 178 } catch (ParseException ex) { 179 ex.printStackTrace(); 180 return null; 181 } catch (InvalidArgumentException ex) { 182 ex.printStackTrace(); 183 return null; 184 } 185 } getListeningPoint()186 public ListeningPointImpl getListeningPoint() { 187 if ( listeningPoint == null ) { 188 if ( this.getSIPStack().isLoggingEnabled()) { 189 this.getSIPStack().getStackLogger().logError("getListeningPoint" + this + 190 " returning null listeningpoint"); 191 192 } 193 } 194 return listeningPoint; 195 } 196 setListeningPoint(ListeningPointImpl lp)197 public void setListeningPoint(ListeningPointImpl lp) { 198 if ( this.getSIPStack().isLoggingEnabled()) { 199 this.getSIPStack().getStackLogger().logDebug("setListeningPoint" + this + 200 " listeningPoint = " + lp); 201 202 } 203 if ( lp.getPort() != this.getPort()) 204 InternalErrorHandler.handleException 205 ("lp mismatch with provider",getSIPStack().getStackLogger()); 206 this.listeningPoint = lp; 207 208 } 209 210 /** 211 * Get the saved IP Address. 212 */ getSavedIpAddress()213 public String getSavedIpAddress() { 214 return this.savedIpAddress; 215 } 216 /** 217 * @return the ip address for this message processor. 218 */ getIpAddress()219 public InetAddress getIpAddress() { 220 return this.ipAddress; 221 } 222 /** 223 * @param ipAddress the ipAddress to set 224 */ setIpAddress(InetAddress ipAddress)225 protected void setIpAddress(InetAddress ipAddress) { 226 this.sentByHostPort.setHost( new Host(ipAddress.getHostAddress())); 227 this.ipAddress = ipAddress; 228 } 229 230 /** 231 * Set the sentby string. This is used for stamping outgoing messages sent 232 * from this listening point. 233 * 234 * @param sentBy 235 */ setSentBy(String sentBy)236 public void setSentBy(String sentBy) throws ParseException { 237 238 int ind = sentBy.indexOf(":"); 239 if (ind == -1) { 240 this.sentByHostPort = new HostPort(); 241 this.sentByHostPort.setHost(new Host(sentBy)); 242 } else { 243 this.sentByHostPort = new HostPort(); 244 this.sentByHostPort.setHost(new Host(sentBy.substring(0, ind))); 245 String portStr = sentBy.substring(ind + 1); 246 try { 247 int port = Integer.parseInt(portStr); 248 this.sentByHostPort.setPort(port); 249 } catch (NumberFormatException ex) { 250 throw new ParseException("Bad format encountered at ", ind); 251 } 252 } 253 this.sentBySet = true; 254 this.sentBy = sentBy; 255 256 } 257 258 /** 259 * Get the sentby string. 260 * 261 */ getSentBy()262 public String getSentBy() { 263 if ( this.sentBy == null && this.sentByHostPort != null) { 264 this.sentBy = this.sentByHostPort.toString(); 265 } 266 return this.sentBy; 267 } 268 269 //////////////////////////////////////////////////////////////////////////////////////// 270 // Abstract methods 271 /////////////////////////////////////////////////////////////////////////////////////// 272 /** 273 * Get the SIP Stack. 274 * 275 * @return the sip stack. 276 */ getSIPStack()277 public abstract SIPTransactionStack getSIPStack(); 278 279 /** 280 * Create a message channel for the specified host/port. 281 * 282 * @return New MessageChannel for this processor. 283 */ createMessageChannel(HostPort targetHostPort)284 public abstract MessageChannel createMessageChannel(HostPort targetHostPort) 285 throws IOException; 286 287 /** 288 * Create a message channel for the specified host/port. 289 * 290 * @return New MessageChannel for this processor. 291 */ createMessageChannel(InetAddress targetHost, int port)292 public abstract MessageChannel createMessageChannel(InetAddress targetHost, 293 int port) throws IOException; 294 295 296 /** 297 * Start our thread. 298 */ start()299 public abstract void start() throws IOException; 300 301 /** 302 * Stop method. 303 */ stop()304 public abstract void stop(); 305 306 /** 307 * Default target port used by this processor. This is 5060 for TCP / UDP 308 */ getDefaultTargetPort()309 public abstract int getDefaultTargetPort(); 310 311 /** 312 * Flags whether this processor is secure or not. 313 */ isSecure()314 public abstract boolean isSecure(); 315 316 /** 317 * Maximum number of bytes that this processor can handle. 318 */ getMaximumMessageSize()319 public abstract int getMaximumMessageSize(); 320 321 /** 322 * Return true if there are pending messages to be processed (which prevents 323 * the message channel from being closed). 324 */ inUse()325 public abstract boolean inUse(); 326 327 328 329 /** 330 * Run method. 331 */ run()332 public abstract void run(); 333 334 /** 335 * @return Returns the sentBySet. 336 */ isSentBySet()337 public boolean isSentBySet() { 338 return sentBySet; 339 } 340 341 342 /** 343 * Get the defalt port for the message processor. 344 * 345 * @param transport 346 * @return -- the default port for the message processor. 347 */ 348 getDefaultPort(String transport)349 public static int getDefaultPort(String transport) { 350 351 return transport.equalsIgnoreCase("TLS")?5061:5060; 352 } 353 354 355 356 } 357