/** * Send an array of bytes. * * @param receiverAddress -- inet address * @param contactPort -- port to connect to. * @param transport -- tcp or udp. * @param retry -- retry to connect if the other end closed connection * @throws IOException -- if there is an IO exception sending message. */ public Socket sendBytes( InetAddress senderAddress, InetAddress receiverAddress, int contactPort, String transport, byte[] bytes, boolean retry) throws IOException { int retry_count = 0; int max_retry = retry ? 2 : 1; // Server uses TCP transport. TCP client sockets are cached int length = bytes.length; if (sipStack.isLoggingEnabled()) { sipStack.logWriter.logDebug( "sendBytes " + transport + " inAddr " + receiverAddress.getHostAddress() + " port = " + contactPort + " length = " + length); } if (transport.compareToIgnoreCase(TCP) == 0) { String key = makeKey(receiverAddress, contactPort); // This should be in a synchronized block ( reported by // Jayashenkhar ( lucent ). try { boolean retval = this.ioSemaphore.tryAcquire( 10000, TimeUnit.MILLISECONDS); // TODO - make this a stack config parameter? if (!retval) { throw new IOException("Could not acquire IO Semaphore after 10 second -- giving up "); } } catch (InterruptedException ex) { throw new IOException("exception in aquiring sem"); } Socket clientSock = getSocket(key); try { while (retry_count < max_retry) { if (clientSock == null) { if (sipStack.isLoggingEnabled()) { sipStack.logWriter.logDebug("inaddr = " + receiverAddress); sipStack.logWriter.logDebug("port = " + contactPort); } // note that the IP Address for stack may not be // assigned. // sender address is the address of the listening point. // in version 1.1 all listening points have the same IP // address (i.e. that of the stack). In version 1.2 // the IP address is on a per listening point basis. clientSock = sipStack .getNetworkLayer() .createSocket(receiverAddress, contactPort, senderAddress); OutputStream outputStream = clientSock.getOutputStream(); writeChunks(outputStream, bytes, length); putSocket(key, clientSock); break; } else { try { OutputStream outputStream = clientSock.getOutputStream(); writeChunks(outputStream, bytes, length); break; } catch (IOException ex) { if (sipStack.isLoggingEnabled()) sipStack.logWriter.logException(ex); // old connection is bad. // remove from our table. removeSocket(key); try { clientSock.close(); } catch (Exception e) { } clientSock = null; retry_count++; } } } } finally { ioSemaphore.release(); } if (clientSock == null) { throw new IOException("Could not connect to " + receiverAddress + ":" + contactPort); } else return clientSock; // Added by Daniel J. Martinez Manzano <*****@*****.**> // Copied and modified from the former section for TCP } else if (transport.compareToIgnoreCase(TLS) == 0) { String key = makeKey(receiverAddress, contactPort); try { boolean retval = this.ioSemaphore.tryAcquire(10000, TimeUnit.MILLISECONDS); if (!retval) throw new IOException("Timeout aquiring IO SEM"); } catch (InterruptedException ex) { throw new IOException("exception in aquiring sem"); } Socket clientSock = getSocket(key); try { while (retry_count < max_retry) { if (clientSock == null) { if (sipStack.isLoggingEnabled()) { sipStack.logWriter.logDebug("inaddr = " + receiverAddress); sipStack.logWriter.logDebug("port = " + contactPort); } if (!sipStack.useTlsAccelerator) { clientSock = sipStack .getNetworkLayer() .createSSLSocket(receiverAddress, contactPort, senderAddress); } else { clientSock = sipStack .getNetworkLayer() .createSocket(receiverAddress, contactPort, senderAddress); } OutputStream outputStream = clientSock.getOutputStream(); writeChunks(outputStream, bytes, length); putSocket(key, clientSock); break; } else { try { OutputStream outputStream = clientSock.getOutputStream(); writeChunks(outputStream, bytes, length); break; } catch (IOException ex) { if (sipStack.isLoggingEnabled()) sipStack.logWriter.logException(ex); // old connection is bad. // remove from our table. removeSocket(key); try { clientSock.close(); } catch (Exception e) { } clientSock = null; retry_count++; } } } } finally { ioSemaphore.release(); } if (clientSock == null) { throw new IOException("Could not connect to " + receiverAddress + ":" + contactPort); } else return clientSock; } else { // This is a UDP transport... DatagramSocket datagramSock = sipStack.getNetworkLayer().createDatagramSocket(); datagramSock.connect(receiverAddress, contactPort); DatagramPacket dgPacket = new DatagramPacket(bytes, 0, length, receiverAddress, contactPort); datagramSock.send(dgPacket); datagramSock.close(); return null; } }