package voip; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.UnknownHostException; import java.io.IOException; import java.util.StringTokenizer; public class RTPManager extends UdpManager { SIPMsg sipMsg = null; boolean doCipher = false; boolean stop = false; RTPManager(SIPMsg sipMsg) { super(); this.sipMsg = sipMsg; System.out.println("RTP Manager: " + myAddr.toString() + ":" + myPort); } public void run() { System.out.println("doCipher = " + doCipher); try { while ( !stop ) { DatagramPacket packet = new DatagramPacket( new byte[Constants.MAX_RTP_PACKET_SIZE], Constants.MAX_RTP_PACKET_SIZE ); // Waits for a datagram packet to arrive. socket.receive( packet ); // Change the address and port number appropriately: DatagramPacket newPacket = rewritePacket( packet ); // Send the modified packet to the guest. if (newPacket != null) socket.send( newPacket ); } socket.close(); } catch ( IOException e ) { System.out.println("Unable to communicate with media proxy or just getting terminated" + e.getMessage()); e.printStackTrace(); socket.close(); } } void setDoCipher(boolean doCipher) { this.doCipher = doCipher; return; } void terminate() { System.out.println("terminating RTP manager..."); stop = true; } protected DatagramPacket rewritePacket(DatagramPacket packet) { DatagramPacket newPacket = new DatagramPacket(new byte[Constants.MAX_RTP_PACKET_SIZE], Constants.MAX_RTP_PACKET_SIZE); String packetStr = new String(packet.getData(),0,packet.getLength()); if ( packet.getAddress().equals(clientAddr) ) // from my client! { // Change the port number in the packet to be mine. String newDP = replaceAddress(packet, guestAddr, guestPort); // Encrypt the data if required. if (doCipher) { byte[] data = SIPMsg.encryptMedia(newDP.getBytes()); if ( data != null ) { newPacket.setData(data); } else return null; } else { newPacket.setData(newDP.getBytes()); } newPacket.setAddress(guestAddr); newPacket.setPort(guestPort); } return newPacket; } private String replaceAddress (DatagramPacket packet, InetAddress addr, int port) { StringBuffer buffer = new StringBuffer(new String(packet.getData(),0,packet.getLength())); String strMyPort = new String(myPort + "(" + myPort + ")"); String strPort = new String(port + "(" + port + ")"); int i = 0; int max = buffer.length(); int nPort = strMyPort.length(); while (i < max) { if ((i = buffer.indexOf(strMyPort, i)) == -1) { // No more matches break; } else { // Replace the port number as proxy's buffer.replace(i, i + nPort, strPort); } i += nPort; } String strMyAddr = new String(myAddr.toString() + "(" + myAddr.toString() + ")"); String strAddr = new String(addr.toString() + "(" + addr.toString() + ")"); i = 0; max = buffer.length(); int nAddr = strMyAddr.length(); while (i < max) { if ((i = buffer.indexOf(strMyAddr, i)) == -1) { // No more matches break; } else { // Replace the port number as proxy's buffer.replace(i, i + nAddr, strAddr); } i += nAddr; } return buffer.toString(); } public InetAddress extractMediaAddr(String packetStr) { int first = packetStr.indexOf("c="); int end = packetStr.indexOf("\r\n", first); StringTokenizer st = new StringTokenizer(packetStr.substring(first, end).trim(), " "); st.nextToken(); // Get rid of "c=IN" st.nextToken(); // Get rid of "IP4" String ipStr = st.nextToken();// String of octet dotted IP address InetAddress addr = null; try { addr = InetAddress.getByName(ipStr); } catch (UnknownHostException e) { logger.error("Unable to create InetAddress: " + e.getMessage()); e.printStackTrace(); } return addr; } public int extractMediaPort(String packetStr) { String headStr = "m=audio "; int index = packetStr.indexOf(headStr); index += headStr.length(); String portStr = packetStr.substring(index, index+5).trim(); return Integer.parseInt(portStr); } public String replaceMediaInfo(String packetStr, String toAddr, String addr, int toPort, int port) { StringBuffer buffer = new StringBuffer(packetStr); if (port != 0 && toPort != 0) { String headStr = "m=audio "; int index = buffer.indexOf(headStr); index += headStr.length(); int portLength = String.valueOf(port).length(); buffer.replace(index, index + portLength, String.valueOf(toPort)); } if (addr != null && toAddr != null) { int index = addr.indexOf("/"); if (index != -1) addr = addr.substring(index + 1); // Get rid of hostname + "/" index = toAddr.indexOf("/"); if (index != -1) toAddr = toAddr.substring(index + 1); // Get rid of hostname + "/" int i = 0; int max = buffer.length(); int nAddr = addr.length(); while (i < max) { if ((i = buffer.indexOf(addr, i)) == -1) { // No more matches break; } else { // Replace the port number as proxy's buffer.replace(i, i + nAddr, toAddr); } i += nAddr; } } return buffer.toString(); } public String updateContentLength(String packetStr, int nKeySize) { StringBuffer buffer = new StringBuffer(packetStr); int beginning = buffer.indexOf(Constants.CONTENT_LENGTH); beginning += Constants.CONTENT_LENGTH.length(); int end = beginning + 3; // HACTICING: The value should be no more than three digit String strNum = buffer.substring(beginning, end).trim(); int lenMsg = Integer.parseInt(strNum); lenMsg += nKeySize; buffer.replace(beginning, end, String.valueOf(lenMsg)); return buffer.toString(); } public String toString() { return "RTPManager (doCipher=" + doCipher + ":\n" + super.toString(); } }