All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jivesoftware.openfire.mediaproxy.MediaProxy Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2005-2008 Jive Software. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jivesoftware.openfire.mediaproxy;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Media Proxy relays UDP traffic between two IPs to provide connectivity between
 * two parties that are behind NAT devices. It also provides connectivity
 * between two parties that are directly connected to the internet or one party on the
 * internet and another behind a NAT.

* * Each connection relay between two parties is called a session. You can setup a MediaProxy * for all network interfaces with an empty constructor, or bind it to a specific interface * with the MediaProxy(String localhost) constructor. The media proxy ONLY works if you * are directly connected to the Internet with a valid IP address.. * * @author Thiago Camargo */ public class MediaProxy implements SessionListener { private static final Logger Log = LoggerFactory.getLogger(MediaProxy.class); final private Map sessions = new ConcurrentHashMap<>(); private String ipAddress; private int minPort = 10000; private int maxPort = 20000; private long idleTime = 60000; // Lifetime of a Channel in Seconds private long lifetime = 9000; /** * Contruct a MediaProxy instance that will listen on a specific network interface. * * @param ipAddress the IP address on this server that will listen for packets. */ public MediaProxy(String ipAddress) { this.ipAddress = ipAddress; } /** * Get the public IP of this media proxy that listen for incomming packets. * * @return the host that listens for incomming packets. */ public String getPublicIP() { return ipAddress; } /** * Returns the max time (in millis) that a session can remain open without * receiving any packets. After this time period elapses, the session is * automatically closed. * * @return the max idle time (in millis). */ public long getIdleTime() { return idleTime; } /** * Sets the max time (in millis) that a session can remain open without * receiving any packets. After this time period elapses, the session is * automatically closed. * * @param idleTime the max idle time in millis. */ public void setIdleTime(long idleTime) { this.idleTime = idleTime; } /** * Returns the list of all currently active and running sessions. * * @return List of the Agents */ public Collection getSessions() { return sessions.values(); } /** * Returns the minimum port value to listen for incoming packets. * * @return the minimum port value. */ public int getMinPort() { return minPort; } /** * Sets the minimum port value to listen from incoming packets. * * @param minPort the minimum port value. */ public void setMinPort(int minPort) { this.minPort = minPort; } /** * Returns the maximum port value to listen for incoming packets. * * @return the maximun port value. */ public int getMaxPort() { return maxPort; } /** * Sets the maximum port value to listen for incoming packets. * * @param maxPort the maximun port value. */ public void setMaxPort(int maxPort) { this.maxPort = maxPort; } /** * Returns the maximum lifetime (in seconds) of a session. After the time period * elapses, the session will be destroyed even if currently active. * * @return the max lifetime of a session (in seconds). */ public long getLifetime() { return lifetime; } /** * Sets the maximum lifetime (in seconds) of a session. After the time period * elapses, the session will be destroyed even if currently active. * * @param lifetime the max lifetime of a session (in seconds). */ public void setLifetime(long lifetime) { this.lifetime = lifetime; } /** * Returns a media proxy session with the specified ID. * * @param sid the session ID. * @return the session or null if the session doesn't exist. */ public MediaProxySession getSession(String sid) { MediaProxySession proxySession = sessions.get(sid); if (proxySession != null) { if (Log.isDebugEnabled()) { Log.debug("MediaProxy: SID: " + sid + " agentSID: " + proxySession.getSID()); return proxySession; } } return null; } /** * Implements Session Listener stopAgent event. * Remove the stopped session from the sessions list. * * @param session the session that stopped */ @Override public void sessionClosed(MediaProxySession session) { sessions.remove(session.getSID()); if (Log.isDebugEnabled()) { Log.debug("MediaProxy: Session: " + session.getSID() + " removed."); } } /** * Add a new Dynamic Session to the mediaproxy for defined IPs and ports. * The IP and port pairs can change depending of the Senders IP and port. * Which means that the IP and port values of the points can dynamic change after the Channel is opened. * When the agent receives a packet from Point A, the channel set the point A IP and port according to * the received packet sender IP and port. * Every packet received from Point B will be relayed to the new Point A IP and port. * When the agent receives a packet from Point B, the channel set the point B IP and port according to * the received packet sender IP and port. * Every packet received from Point A will be relayed to the new Point B IP and port. * Create a dynamic channel between two IPs. ( Dynamic Point A - Dynamic Point B ) * * @param id id of the candidate returned (Could be a Jingle session ID) * @param creator the agent creator name or description * @param hostA the hostname or IP of the point A of the Channel * @param portA the port number point A of the Channel * @param hostB the hostname or IP of the point B of the Channel * @param portB the port number point B of the Channel * @return the added ProxyCandidate */ public ProxyCandidate addRelayAgent(String id, String creator, String hostA, int portA, String hostB, int portB) { RelaySession session = new RelaySession(id, creator, ipAddress, hostA, portA, hostB, portB, minPort, maxPort); sessions.put(id, session); session.addKeepAlive(idleTime); session.addLifeTime(lifetime); session.addAgentListener(this); return session; } /** * Add a new Dynamic Session to the mediaproxy WITHOUT defined IPs and ports. * The IP and port pairs WILL change depending of the Senders IP and port. * Which means that the IP and port values of the points will dynamic change after the Channel is opened * and received packet from both points. * When the agent receives a packet from Point A, the channel set the point A IP and port according to * the received packet sender IP and port. * Every packet received from Point B will be relayed to the new Point A IP and port. * When the agent receives a packet from Point B, the channel set the point B IP and port according to * the received packet sender IP and port. * Every packet received from Point A will be relayed to the new Point B IP and port. * Create a dynamic channel between two IPs. ( Dynamic Point A - Dynamic Point B ) * * @param id id of the candidate returned (Could be a Jingle session ID) * @param creator the agent creator name or description * @return the added ProxyCandidate */ public ProxyCandidate addRelayAgent(String id, String creator) { return addRelayAgent(id, creator, ipAddress, 40000, ipAddress, 40004); } /** * Stop every running sessions. */ void stopProxy() { for (MediaProxySession session : getSessions()) { try { session.clearAgentListeners(); session.stopAgent(); } catch (Exception e) { Log.error("Error cleaning up media proxy sessions", e); } } sessions.clear(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy