diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java new file mode 100644 index 000000000..a1bf61d2f --- /dev/null +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/HttpServer.java @@ -0,0 +1,174 @@ +/** + * $RCSfile$ + * $Revision$ + * $Date$ + * + * Copyright (C) 2002-2006 Jive Software. All rights reserved. + * ==================================================================== + * The Jive Software License (based on Apache Software License, Version 1.1) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by + * Jive Software (http://www.jivesoftware.com)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Smack" and "Jive Software" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please + * contact webmaster@jivesoftware.com. + * + * 5. Products derived from this software may not be called "Smack", + * nor may "Smack" appear in their name, without prior written + * permission of Jive Software. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + */ + +package org.jivesoftware.smackx.jingle.nat; + +import java.net.*; +import java.io.*; +import java.util.*; +import java.lang.*; + +/** + * A very Simple HTTP Server + */ +public class HttpServer { + + public HttpServer(int port) { + ServerSocket server_socket; + + try { + + server_socket = new ServerSocket(port); + System.out.println("httpServer running on port " + + server_socket.getLocalPort()); + + while (true) { + Socket socket = server_socket.accept(); + System.out.println("New connection accepted " + + socket.getInetAddress() + + ":" + socket.getPort()); + + try { + HttpRequestHandler request = + new HttpRequestHandler(socket); + + Thread thread = new Thread(request); + + thread.start(); + } + catch (Exception e) { + System.out.println(e); + } + } + } + + catch (IOException e) { + System.out.println(e); + } + + } + + public static void main(String args[]) { + HttpServer httpServer = new HttpServer(Integer.parseInt(args[0])); + } + + class HttpRequestHandler implements Runnable { + + final static String CRLF = "\r\n"; + Socket socket; + InputStream input; + OutputStream output; + BufferedReader br; + + public HttpRequestHandler(Socket socket) throws Exception { + this.socket = socket; + this.input = socket.getInputStream(); + this.output = socket.getOutputStream(); + this.br = new BufferedReader(new InputStreamReader(socket.getInputStream())); + } + + public void run() { + try { + processRequest(); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + private void processRequest() throws Exception { + while (true) { + + String headerLine = br.readLine(); + System.out.println(headerLine); + if (headerLine.equals(CRLF) || headerLine.equals("")) break; + + StringTokenizer s = new StringTokenizer(headerLine); + String temp = s.nextToken(); + + if (temp.equals("GET")) { + + String serverLine = "Server: Simple httpServer"; + String contentTypeLine = "text"; + String entityBody = ""; + String contentLengthLine; + String statusLine = "HTTP/1.0 200 OK" + CRLF; + contentLengthLine = "Content-Length: " + + (new Integer(entityBody.length())).toString() + CRLF; + contentTypeLine = "text/html"; + + output.write(statusLine.getBytes()); + + output.write(serverLine.getBytes()); + + output.write(contentTypeLine.getBytes()); + output.write(contentLengthLine.getBytes()); + + output.write(CRLF.getBytes()); + + output.write(entityBody.getBytes()); + + } + } + + try { + output.close(); + br.close(); + socket.close(); + } + catch (Exception e) { + // Do Nothing + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java new file mode 100644 index 000000000..87ab2de24 --- /dev/null +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeClient.java @@ -0,0 +1,171 @@ +/** + * $RCSfile$ + * $Revision$ + * $Date$ + * + * Copyright (C) 2002-2006 Jive Software. All rights reserved. + * ==================================================================== + * The Jive Software License (based on Apache Software License, Version 1.1) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by + * Jive Software (http://www.jivesoftware.com)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Smack" and "Jive Software" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please + * contact webmaster@jivesoftware.com. + * + * 5. Products derived from this software may not be called "Smack", + * nor may "Smack" appear in their name, without prior written + * permission of Jive Software. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + */ +package org.jivesoftware.smackx.jingle.nat; + +import java.net.DatagramSocket; +import java.net.Socket; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A Simple and Experimental Bridge. + * It Creates a TCP Socket That Connects to another TCP Socket Listener and forwards every packets received to an UDP Listener. + * And forwards every packets received in UDP Socket, to the TCP Server + */ +public class TcpUdpBridgeClient { + + private String remoteTcpHost = null; + private String remoteUdpHost = null; + private int remoteTcpPort = -1; + private int remoteUdpPort = -1; + private int localUdpPort = -1; + + private DatagramSocket localUdpSocket; + private Socket localTcpSocket; + + public TcpUdpBridgeClient(String remoteTcpHost, String remoteUdpHost, int remoteTcpPort, int remoteUdpPort) { + this.remoteTcpHost = remoteTcpHost; + this.remoteUdpHost = remoteUdpHost; + this.remoteTcpPort = remoteTcpPort; + this.remoteUdpPort = remoteUdpPort; + + try { + localTcpSocket = new Socket(remoteTcpHost, remoteTcpPort); + localUdpSocket = new DatagramSocket(0); + localUdpPort = localUdpSocket.getLocalPort(); + System.out.println("UDP: " + localUdpSocket.getLocalPort()); + } + catch (IOException e) { + e.printStackTrace(); + } + startBridge(); + } + + public void startBridge() { + + + final Thread process = new Thread(new Runnable() { + + public void run() { + try { + OutputStream out = localTcpSocket.getOutputStream(); + + while (true) { + + byte b[] = new byte[500]; + DatagramPacket p = new DatagramPacket(b, 500); + + localUdpSocket.receive(p); + if (p.getLength() == 0) continue; + + System.out.println("UDP Client Received and Sending to TCP Server:"+new String(p.getData(),0,p.getLength(),"UTF-8")); + + out.write(p.getData(), 0, p.getLength()); + out.flush(); + System.out.println("Client Flush"); + + } + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + }); + + new Thread(new Runnable() { + + public void run() { + try { + + InputStream in = localTcpSocket.getInputStream(); + InetAddress remoteHost = InetAddress.getByName(remoteUdpHost); + process.start(); + + while (true) { + byte b[] = new byte[500]; + + int s = in.read(b); + //if (s == -1) continue; + + System.out.println("TCP Client:" +new String(b,0,s,"UTF-8")); + + DatagramPacket udpPacket = new DatagramPacket(b, s); + + udpPacket.setAddress(remoteHost); + udpPacket.setPort(remoteUdpPort); + + localUdpSocket.send(udpPacket); + + } + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + }).start(); + } + + public Socket getLocalTcpSocket() { + return localTcpSocket; + } + + public DatagramSocket getLocalUdpSocket() { + return localUdpSocket; + } +} diff --git a/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeServer.java b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeServer.java new file mode 100644 index 000000000..3f32b6fce --- /dev/null +++ b/jingle/extension/source/org/jivesoftware/smackx/jingle/nat/TcpUdpBridgeServer.java @@ -0,0 +1,117 @@ +package org.jivesoftware.smackx.jingle.nat; + +import java.net.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * A Simple and Experimental Bridge. + * It Creates a TCP Socket Listeners for Connections and forwards every packets received to an UDP Listener. + * And forwards every packets received in UDP Socket, to the TCP Client + */ +public class TcpUdpBridgeServer { + + private String remoteTcpHost = null; + private String remoteUdpHost = null; + private int remoteTcpPort = -1; + private int remoteUdpPort = -1; + private int localUdpPort = -1; + + private DatagramSocket localUdpSocket; + private Socket localTcpSocket; + private ServerSocket serverTcpSocket; + + public TcpUdpBridgeServer(String remoteTcpHost, String remoteUdpHost, int remoteTcpPort, int remoteUdpPort) { + this.remoteTcpHost = remoteTcpHost; + this.remoteUdpHost = remoteUdpHost; + this.remoteTcpPort = remoteTcpPort; + this.remoteUdpPort = remoteUdpPort; + + try { + serverTcpSocket = new ServerSocket(remoteTcpPort); + localUdpSocket = new DatagramSocket(0); + localUdpPort = localUdpSocket.getLocalPort(); + System.out.println("UDP: " + localUdpSocket.getLocalPort()); + } + catch (IOException e) { + e.printStackTrace(); + } + startBridge(); + } + + public void startBridge() { + + final Thread process = new Thread(new Runnable() { + + public void run() { + try { + OutputStream out = localTcpSocket.getOutputStream(); + + while (true) { + + byte b[] = new byte[500]; + DatagramPacket p = new DatagramPacket(b, 500); + + localUdpSocket.receive(p); + if (p.getLength() == 0) continue; + + System.out.println("UDP Server Received and Sending to TCP Client:" + new String(p.getData(), 0, p.getLength(), "UTF-8")); + + out.write(p.getData(), 0, p.getLength()); + out.flush(); + System.out.println("Server Flush"); + } + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + }); + + new Thread(new Runnable() { + + public void run() { + try { + + localTcpSocket = serverTcpSocket.accept(); + process.start(); + InputStream in = localTcpSocket.getInputStream(); + InetAddress remoteHost = InetAddress.getByName(remoteUdpHost); + + while (true) { + byte b[] = new byte[500]; + + int s = in.read(b); + //if (s == -1) continue; + + System.out.println("TCP Server:" + new String(b, 0, s, "UTF-8")); + + DatagramPacket udpPacket = new DatagramPacket(b, s); + + udpPacket.setAddress(remoteHost); + udpPacket.setPort(remoteUdpPort); + + localUdpSocket.send(udpPacket); + + } + + } + catch (IOException e) { + e.printStackTrace(); + } + } + + }).start(); + } + + public Socket getLocalTcpSocket() { + return localTcpSocket; + } + + public DatagramSocket getLocalUdpSocket() { + return localUdpSocket; + } +}