1600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 2600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Conditions Of Use 3600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 4600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software was developed by employees of the National Institute of 5600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Standards and Technology (NIST), an agency of the Federal Government. 6600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pursuant to title 15 Untied States Code Section 105, works of NIST 7600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * employees are not subject to copyright protection in the United States 8600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and are considered to be in the public domain. As a result, a formal 9600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * license is not needed to use the software. 10600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 11600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software is provided by NIST as a service and is expressly 12600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * AND DATA ACCURACY. NIST does not warrant or make any representations 16600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * regarding the use of the software or the results thereof, including but 17600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * not limited to the correctness, accuracy, reliability or usefulness of 18600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * the software. 19600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 20600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Permission to use this software is contingent upon your acceptance 21600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * of the terms of this agreement 22600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 23600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * . 24600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 25600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 26600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/****************************************************************************** 27600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 28600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ******************************************************************************/ 29600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpackage gov.nist.javax.sip.stack; 30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.net.Socket; 32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.net.ServerSocket; 33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.io.IOException; 34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.net.SocketException; 35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.core.*; 36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.net.*; 37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.*; 38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Acknowledgement: Jeff Keyser suggested that a Stop mechanism be added to this. Niklas Uhrberg 41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * suggested that a means to limit the number of simultaneous active connections should be added. 42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Mike Andrews suggested that the thread be accessible so as to implement clean stop using 43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Thread.join(). Roger M. Persson contributed a bug fix for cleanup on stop(). 44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/** 48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Sit in a loop waiting for incoming tcp connections and start a new thread to handle each new 49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * connection. This is the active object that creates new TCP MessageChannels (one for each new 50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * accept socket). 51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @version 1.2 $Revision: 1.31 $ $Date: 2009/08/31 16:18:00 $ 53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @author M. Ranganathan <br/> 55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic class TCPMessageProcessor extends MessageProcessor { 59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected int nConnections; 61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private boolean isRunning; 63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private Hashtable tcpMessageChannels; 65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private ArrayList<TCPMessageChannel> incomingTcpMessageChannels; 67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private ServerSocket sock; 69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected int useCount; 71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Constructor. 74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param sipStack SIPStack structure. 76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param port port where this message processor listens. 77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected TCPMessageProcessor(InetAddress ipAddress, SIPTransactionStack sipStack, int port) { 79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang super(ipAddress, port, "tcp",sipStack); 80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipStack = sipStack; 82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.tcpMessageChannels = new Hashtable(); 84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.incomingTcpMessageChannels = new ArrayList<TCPMessageChannel>(); 85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Start the processor. 89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void start() throws IOException { 91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Thread thread = new Thread(this); 92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang thread.setName("TCPMessageProcessorThread"); 93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang thread.setPriority(Thread.MAX_PRIORITY); 94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang thread.setDaemon(true); 95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sock = sipStack.getNetworkLayer().createServerSocket(getPort(), 0, getIpAddress()); 96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (getIpAddress().getHostAddress().equals(IN_ADDR_ANY) 97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang || getIpAddress().getHostAddress().equals(IN6_ADDR_ANY)) { 98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Store the address to which we are actually bound 99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang super.setIpAddress(sock.getInetAddress()); 100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.isRunning = true; 103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang thread.start(); 104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Run method for the thread that gets created for each accept socket. 109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void run() { 111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Accept new connectins on our socket. 112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang while (this.isRunning) { 113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang synchronized (this) { 115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // sipStack.maxConnections == -1 means we are 116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // willing to handle an "infinite" number of 117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // simultaneous connections (no resource limitation). 118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This is the default behavior. 119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang while (sipStack.maxConnections != -1 120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && this.nConnections >= sipStack.maxConnections) { 121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.wait(); 123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!this.isRunning) 125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return; 126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (InterruptedException ex) { 127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang break; 128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.nConnections++; 131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Socket newsock = sock.accept(); 134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang getSIPStack().getStackLogger().logDebug("Accepting new connection!"); 136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Note that for an incoming message channel, the 138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // thread is already running 139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang incomingTcpMessageChannels.add(new TCPMessageChannel(newsock, sipStack, this)); 141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (SocketException ex) { 142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.isRunning = false; 143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Problem accepting connection. 145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang getSIPStack().getStackLogger().logException(ex); 147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (Exception ex) { 149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 155600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Return the transport string. 156600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 157600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return the transport string 158600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 159600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public String getTransport() { 160600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return "tcp"; 161600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 162600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 163600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 164600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Returns the stack. 165600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 166600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return my sip stack. 167600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 168600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public SIPTransactionStack getSIPStack() { 169600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return sipStack; 170600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 171600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 172600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 173600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Stop the message processor. Feature suggested by Jeff Keyser. 174600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 175600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void stop() { 176600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang isRunning = false; 177600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // this.listeningPoint = null; 178600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 179600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sock.close(); 180600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException e) { 181600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang e.printStackTrace(); 182600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 183600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 184600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Collection en = tcpMessageChannels.values(); 185600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (Iterator it = en.iterator(); it.hasNext();) { 186600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TCPMessageChannel next = (TCPMessageChannel) it.next(); 187600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang next.close(); 188600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 189600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // RRPN: fix 190600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (Iterator incomingMCIterator = incomingTcpMessageChannels.iterator(); incomingMCIterator 191600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .hasNext();) { 192600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TCPMessageChannel next = (TCPMessageChannel) incomingMCIterator.next(); 193600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang next.close(); 194600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 195600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 196600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.notify(); 197600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 198600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 199600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected synchronized void remove(TCPMessageChannel tcpMessageChannel) { 200600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 201600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String key = tcpMessageChannel.getKey(); 202600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 203600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug(Thread.currentThread() + " removing " + key); 204600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 205600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 206600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** May have been removed already */ 207600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (tcpMessageChannels.get(key) == tcpMessageChannel) { 208600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.tcpMessageChannels.remove(key); 209600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 210600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 211600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang incomingTcpMessageChannels.remove(tcpMessageChannel); 212600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 213600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 214600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized MessageChannel createMessageChannel(HostPort targetHostPort) 215600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws IOException { 216600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String key = MessageChannel.getKey(targetHostPort, "TCP"); 217600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (tcpMessageChannels.get(key) != null) { 218600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (TCPMessageChannel) this.tcpMessageChannels.get(key); 219600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 220600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TCPMessageChannel retval = new TCPMessageChannel(targetHostPort.getInetAddress(), 221600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang targetHostPort.getPort(), sipStack, this); 222600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.tcpMessageChannels.put(key, retval); 223600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.isCached = true; 224600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 225600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("key " + key); 226600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("Creating " + retval); 227600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 228600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 229600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 230600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 231600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 232600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected synchronized void cacheMessageChannel(TCPMessageChannel messageChannel) { 233600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String key = messageChannel.getKey(); 234600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TCPMessageChannel currentChannel = (TCPMessageChannel) tcpMessageChannels.get(key); 235600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (currentChannel != null) { 236600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 237600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("Closing " + key); 238600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang currentChannel.close(); 239600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 240600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 241600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("Caching " + key); 242600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.tcpMessageChannels.put(key, messageChannel); 243600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 244600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 245600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 246600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized MessageChannel createMessageChannel(InetAddress host, int port) 247600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws IOException { 248600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 249600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String key = MessageChannel.getKey(host, port, "TCP"); 250600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (tcpMessageChannels.get(key) != null) { 251600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (TCPMessageChannel) this.tcpMessageChannels.get(key); 252600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 253600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TCPMessageChannel retval = new TCPMessageChannel(host, port, sipStack, this); 254600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.tcpMessageChannels.put(key, retval); 255600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.isCached = true; 256600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 257600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("key " + key); 258600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("Creating " + retval); 259600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 260600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 261600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 262600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (UnknownHostException ex) { 263600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new IOException(ex.getMessage()); 264600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 265600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 266600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 267600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 268600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * TCP can handle an unlimited number of bytes. 269600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 270600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public int getMaximumMessageSize() { 271600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Integer.MAX_VALUE; 272600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 273600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 274600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean inUse() { 275600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return this.useCount != 0; 276600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 277600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 278600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 279600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Default target port for TCP 280600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 281600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public int getDefaultTargetPort() { 282600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return 5060; 283600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 284600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 285600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 286600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * TCP is not a secure protocol. 287600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 288600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean isSecure() { 289600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 290600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 291600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang} 292