Commit 3e1aa057 authored by Thiago Camargo's avatar Thiago Camargo Committed by thiago

Multiple STUN Servers Support

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@7647 b35dd754-fafc-0310-a699-88a17e54d16e
parent d0159f47
......@@ -2124,5 +2124,14 @@ stun.settings.secondaryaddress = Sekund\u00e1rn\u00ed adresa
stun.settings.primaryport = Prim\u00e1rn\u00ed port
stun.settings.secondaryport = Sekund\u00e1rn\u00ed
stun.settings.enabled = Povoleno
stun.settings.change = Zm\u011bna
stun.settings.change = Zm\u011bna\
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
index.certificate-warning=Found RSA certificate that is not valid for the server domain.
\ No newline at end of file
......@@ -2043,6 +2043,14 @@ stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.change = Change
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
admin.console.restarting=Restarting admin console...
global.click_test=Click to test...
global.day=day
......
......@@ -2340,7 +2340,15 @@ stun.settings.secondaryaddress = Secondary Address
stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.localenabled = Local Server Enabled
stun.settings.change = Change
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
# Import signed certificate page
......
......@@ -2123,4 +2123,12 @@ stun.settings.primaryport = Puerto Primario
stun.settings.secondaryport = Puerto Secundario
stun.settings.enabled = Habilitado
stun.settings.change = Cambiar
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
index.certificate-warning=Se ha encontrado un certificado RSA que no es v\u00e1lido para el dominio del servidor.
\ No newline at end of file
......@@ -1710,6 +1710,14 @@ stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.change = Change
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
httpbind.settings.enabled.legend=Service Enabled
httpbind.settings.info=HTTP binding allows clients using the HTTP protocol to connect to Wildfire.
httpbind.settings.label_disable=Disabled
......
......@@ -2050,6 +2050,14 @@ stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.change = Change
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
admin.console.restarting=Restarting admin console...
global.click_test=Click to test...
global.day=day
......
......@@ -2025,6 +2025,14 @@ stun.settings.primaryport = Primary Port Value
stun.settings.secondaryport = Secondary Port Value
stun.settings.enabled = Enabled
stun.settings.change = Change
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
global.click_test=Click to test...
global.day=day
global.days=days
......
......@@ -2123,4 +2123,12 @@ stun.settings.primaryport = Porta Prim\u00e1ria
stun.settings.secondaryport = Porta Secund\u00e1ria
stun.settings.enabled = Habilitado
stun.settings.change = Modificar
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
setup.admin.settings.username-error=Nenhum usu\u00e1rio informado, ou o usu\u00e1rio informado n\u00e3o foi encontrado.
\ No newline at end of file
......@@ -1903,4 +1903,12 @@ stun.settings.secondaryaddress = \u4e8c\u7ea7\u5730\u5740
stun.settings.primaryport = \u4e00\u7ea7\u7aef\u53e3\u503c
stun.settings.secondaryport = \u4e8c\u7ea7\u7aef\u53e3\u503c
stun.settings.enabled = \u542f\u7528
stun.settings.change = \u53d8\u66f4
stun.settings.change = \u53d8\u66f4\
stun.external.title = External Stun Servers
stun.external.comment = Server will also send the following address(es) to client.
stun.external.server = Server
stun.external.port = Port
stun.external.error = You must inform Server and Port.
stun.external.add = Add
stun.external.delete = Delete
......@@ -50,14 +50,14 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
private StunServer stunServer = null;
private String name = "stun";
private boolean enabled = false;
private boolean localEnabled = false;
private String primaryAddress;
private String secondaryAddress;
private int primaryPort = 3478;
private int secondaryPort = 3479;
private String externalServerAddress = null;
private int externalServerPort = 3478;
private List<StunServerAddress> externalServers = null;
public static final String NAMESPACE = "google:jingleinfo";
......@@ -72,11 +72,11 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
* Load config using JiveGlobals
*/
private void loadSTUNConfig() {
primaryAddress = JiveGlobals.getProperty("stun.address.primary");
secondaryAddress = JiveGlobals.getProperty("stun.address.secondary");
externalServerAddress = JiveGlobals.getProperty("stun.external.address");
externalServerAddress = JiveGlobals.getProperty("stun.external.port");
externalServers = getStunServerAddresses(JiveGlobals.getProperty("stun.external.addresses"));
if (primaryAddress == null || primaryAddress.equals(""))
primaryAddress = JiveGlobals.getProperty("xmpp.domain",
......@@ -99,6 +99,7 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
}
this.enabled = JiveGlobals.getBooleanProperty("stun.enabled", true);
this.localEnabled = JiveGlobals.getBooleanProperty("stun.local.enabled", true);
}
......@@ -118,13 +119,15 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
public void start() {
if (isEnabled()) {
startServer();
startService();
if (isLocalEnabled())
startLocalServer();
} else {
XMPPServer.getInstance().getIQDiscoItemsHandler().removeServerItemsProvider(this);
}
}
public void startServer() {
public void startLocalServer() {
try {
InetAddress primary = InetAddress.getByName(primaryAddress);
......@@ -136,34 +139,37 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
stunServer.start();
} else
setEnabled(false);
setLocalEnabled(false);
} catch (SocketException e) {
Log.error("Disabling STUN server", e);
setEnabled(false);
setLocalEnabled(false);
} catch (UnknownHostException e) {
Log.error("Disabling STUN server", e);
setEnabled(false);
setLocalEnabled(false);
}
}
if (stunServer != null) {
routingTable.addRoute(getAddress(), this);
XMPPServer server = XMPPServer.getInstance();
server.getIQDiscoItemsHandler().addServerItemsProvider(this);
}
public void startService() {
routingTable.addRoute(getAddress(), this);
XMPPServer server = XMPPServer.getInstance();
server.getIQDiscoItemsHandler().addServerItemsProvider(this);
}
public void stop() {
super.stop();
this.enabled = false;
if (stunServer != null)
stunServer.stop();
stunServer = null;
XMPPServer.getInstance().getIQDiscoItemsHandler().removeComponentItem(getAddress().toString());
if (routingTable != null)
routingTable.removeRoute(getAddress());
}
public void stopLocal() {
if (stunServer != null)
stunServer.stop();
stunServer = null;
}
public String getName() {
return serviceName;
}
......@@ -210,10 +216,19 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
return;
} else if (NAMESPACE.equals(namespace)) {
Element stun = childElementCopy.addElement("stun");
Element server = stun.addElement("server");
server.addAttribute("host", primaryAddress);
server.addAttribute("udp", String.valueOf(primaryPort));
if (isEnabled()) {
Element stun = childElementCopy.addElement("stun");
if (isLocalEnabled()) {
Element server = stun.addElement("server");
server.addAttribute("host", primaryAddress);
server.addAttribute("udp", String.valueOf(primaryPort));
}
for (StunServerAddress stunServerAddress : externalServers) {
Element server = stun.addElement("server");
server.addAttribute("host", stunServerAddress.getServer());
server.addAttribute("udp", stunServerAddress.getPort());
}
}
} else {
// Answer an error since the server can't handle the requested namespace
......@@ -245,6 +260,31 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
return new JID(null, getServiceDomain(), null);
}
public List<StunServerAddress> getExternalServers() {
return externalServers;
}
public void addExternalServer(String server, String port) {
externalServers.add(new StunServerAddress(server, port));
String property = "";
for (StunServerAddress stunServerAddress : externalServers) {
if (!property.equals("")) property += ";";
property += stunServerAddress.getServer() + ":" + stunServerAddress.getPort();
}
JiveGlobals.setProperty("stun.external.addresses", property);
}
public void removeExternalServer(int index) {
externalServers.remove(index);
String property = "";
for (StunServerAddress stunServerAddress : externalServers) {
if (!property.equals("")) property += ";";
property += stunServerAddress.getServer() + ":" + stunServerAddress.getPort();
}
JiveGlobals.setProperty("stun.external.addresses", property);
}
public Iterator<DiscoServerItem> getItems() {
List<DiscoServerItem> items = new ArrayList<DiscoServerItem>();
if (!isEnabled()) {
......@@ -313,20 +353,46 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
return enabled;
}
/**
* Get if the local STUN Server is enabled.
*
* @return enabled
*/
public boolean isLocalEnabled() {
return localEnabled;
}
/**
* Set the service enable status.
*
* @param enabled boolean to enable or disable
* @param enabled boolean to enable or disable
* @param localEnabled local Server enable or disable
*/
public void setEnabled(boolean enabled) {
public void setEnabled(boolean enabled, boolean localEnabled) {
this.enabled = enabled;
this.localEnabled = localEnabled;
if (isEnabled()) {
startServer();
startService();
if (isLocalEnabled())
startLocalServer();
} else {
stop();
}
}
/**
* Set the Local STUN Server enable status.
*
* @param enabled boolean to enable or disable
*/
public void setLocalEnabled(boolean enabled) {
this.localEnabled = enabled;
if (isLocalEnabled())
startLocalServer();
else
stopLocal();
}
/**
* Get the secondary Port used by the STUN server
*
......@@ -378,7 +444,62 @@ public class STUNService extends BasicModule implements ServerItemsProvider, Rou
}
}
} catch (Exception e) {
// Do Nothing
}
return list;
}
/**
* Provides easy abstract to store STUN Server Addresses and Ports
*/
public class StunServerAddress {
private String server;
private String port;
public StunServerAddress(String server, String port) {
this.server = server;
this.port = port;
}
/**
* Get the Host Address
*
* @return Host Address
*/
public String getServer() {
return server;
}
/**
* Get STUN port
*
* @return the Server Port
*/
public String getPort() {
return port;
}
}
/**
* Abstraction method used to convert a String into a STUN Server Address List
*
* @param addresses the String representation of Server Addresses with their respective Ports (server1:port1;server2:port2)
* @return STUN Server Addresses List
*/
public List<StunServerAddress> getStunServerAddresses(String addresses) {
List<StunServerAddress> list = new ArrayList<StunServerAddress>();
if (addresses == null || addresses.equals("")) return list;
String servers[] = addresses.split(";");
for (String server : servers) {
String address[] = server.split(":");
list.add(new StunServerAddress(address[0], address[1]));
}
return list;
}
}
......@@ -51,14 +51,16 @@
STUNService stunService = XMPPServer.getInstance().getSTUNService();
boolean save = request.getParameter("save") != null;
boolean add = request.getParameter("add") != null;
int remove = ParamUtils.getIntParameter(request, "remove", -1);
boolean success = false;
boolean enabled = false;
boolean localEnabled = false;
String primaryAddress;
String secondaryAddress;
int primaryPort = 3478;
int secondaryPort = 3576;
int secondaryPort = 3479;
if (save) {
primaryPort = ParamUtils.getIntParameter(request, "primaryPort", primaryPort);
......@@ -76,23 +78,47 @@
enabled = ParamUtils.getBooleanParameter(request, "enabled", enabled);
JiveGlobals.setProperty("stun.enabled", String.valueOf(enabled));
localEnabled = ParamUtils.getBooleanParameter(request, "localEnabled", localEnabled);
JiveGlobals.setProperty("stun.local.enabled", String.valueOf(localEnabled));
stunService.stop();
stunService.initialize(XMPPServer.getInstance());
stunService.setEnabled(enabled);
if (!enabled) localEnabled = false;
stunService.setEnabled(enabled, localEnabled);
success = stunService.isEnabled() == enabled && stunService.isLocalEnabled() == localEnabled;
} else if (remove > -1) {
stunService.removeExternalServer(remove);
success = true;
} else if (add) {
String server = ParamUtils.getParameter(request, "externalServer", true);
String port = ParamUtils.getParameter(request, "externalPort", true);
success = stunService.isEnabled() == enabled;
if (server != null && port != null)
if (!server.equals("") && !port.equals("")) {
if (server.indexOf(';') == -1 && server.indexOf(',') == -1 && server.indexOf('@') == -1) {
if (port.indexOf(';') == -1 && port.indexOf(',') == -1 && port.indexOf('@') == -1) {
stunService.addExternalServer(server, port);
success = true;
}
}
}
}
%>
<html>
<head>
<title><fmt:message key="stun.settings.title" /></title>
<title>
<fmt:message key="stun.settings.title"/>
</title>
<meta name="pageID" content="stun-settings"/>
</head>
<body>
<p>
<fmt:message key="stun.settings.desc" />
<fmt:message key="stun.settings.desc"/>
</p>
<% if (success) { %>
......@@ -103,7 +129,9 @@
<tr>
<td class="jive-icon"><img src="images/success-16x16.gif" width="16" height="16"
border="0" alt="Success"></td>
<td class="jive-icon-label"><fmt:message key="stun.settings.success" /></td>
<td class="jive-icon-label">
<fmt:message key="stun.settings.success"/>
</td>
</tr>
</tbody>
</table>
......@@ -118,7 +146,25 @@
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16"
border="0"></td>
<td class="jive-icon-label"><fmt:message key="stun.settings.error" />
<td class="jive-icon-label">
<fmt:message key="stun.settings.error"/>
</td>
</tr>
</tbody>
</table>
</div>
<br>
<% } else if (add) { %>
<div class="jive-error">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="jive-icon"><img src="images/error-16x16.gif" width="16" height="16"
border="0"></td>
<td class="jive-icon-label">
<fmt:message key="stun.external.error"/>
</td>
</tr>
</tbody>
......@@ -128,86 +174,185 @@
<% } %>
<form action="" method="post" name="settings">
<div class="jive-contentBoxHeader">
<fmt:message key="stun.settings.title"/>
</div>
<div class="jive-contentBox">
<p>
<fmt:message key="stun.settings.comment"/>
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<tr>
<td align="left">
<fmt:message key="stun.settings.primaryaddress"/>
:&nbsp<select size="1"
maxlength="100"
name="primaryAddress"
align="left">
<option value="<%=stunService.getPrimaryAddress()%>"><%=stunService.getPrimaryAddress()%>
<%
List<InetAddress> addresses = stunService.getAddresses();
for(InetAddress iaddress:addresses){
if(!iaddress.getHostAddress().equals(stunService.getPrimaryAddress())){
%>
<option value="<%=iaddress.getHostAddress()%>"><%=iaddress.getHostAddress()%>
</option>
<%
}
}
String sname = JiveGlobals.getProperty("xmpp.domain", JiveGlobals.getXMLProperty("network.interface", "localhost"));
%>
<option value="<%=sname%>"><%=sname%>
</option>
</td>
</tr>
<tr>
<td align="left">
<fmt:message key="stun.settings.secondaryaddress"/>
:&nbsp<select size="1"
maxlength="100"
name="secondaryAddress"
align="left">
<option value="<%=stunService.getSecondaryAddress()%>"><%=stunService.getSecondaryAddress()%>
</option>
<%
for (InetAddress iaddress : addresses) {
if (!iaddress.getHostAddress().equals(stunService.getSecondaryAddress())) {
%>
<option value="<%=iaddress.getHostAddress()%>"><%=iaddress.getHostAddress()%>
</option>
<% }
}%>
<option value="127.0.0.1">127.0.0.1</option>
</select>
</td>
</tr>
<tr>
<td align="left">
<fmt:message key="stun.settings.primaryport"/>
:&nbsp<input type="text" size="20"
maxlength="100"
name="primaryPort"
value="<%=stunService.getPrimaryPort()%>"
align="left">
</td>
</tr>
<tr>
<td align="left">
<fmt:message key="stun.settings.secondaryport"/>
:&nbsp<input type="text" size="20"
maxlength="100"
name="secondaryPort"
value="<%=stunService.getSecondaryPort()%>"
align="left">
</td>
</tr>
<tr>
<td align="left">
<fmt:message key="stun.settings.localenabled"/>
:&nbsp<input type="checkbox"
name="localEnabled"
<%=stunService.isLocalEnabled()?"checked":""%>
align="left">
</td>
</tr>
<tr>
<td align="left">
<fmt:message key="stun.settings.enabled"/>
:&nbsp<input type="checkbox"
name="enabled"
<%=stunService.isEnabled()?"checked":""%>
align="left">
</td>
</tr>
<tr>
<td>
&nbsp;
</td>
</tr>
<tr>
<td>
<input type="hidden" name="save">
<input type="button" name="set" value="<fmt:message key="stun.settings.change" />"
onclick="checkAndSubmit()">
</td>
</tr>
</tbody>
</table>
</div>
</form>
<form action="" method="post" name="add">
<div class="jive-contentBoxHeader">
<fmt:message key="stun.settings.title" />
<fmt:message key="stun.external.title"/>
</div>
<div class="jive-contentBox">
<p>
<fmt:message key="stun.settings.comment" />
<fmt:message key="stun.external.comment"/>
</p>
<table cellpadding="3" cellspacing="0" border="0" width="100%">
<tbody>
<table cellpadding="3" cellspacing="0" border="0" width="300">
<thead>
<tr>
<td align="left"><fmt:message key="stun.settings.primaryaddress" />:&nbsp<select size="1"
maxlength="100"
name="primaryAddress"
align="left">
<option value="<%=stunService.getPrimaryAddress()%>"><%=stunService.getPrimaryAddress()%>
<%
List<InetAddress> addresses = stunService.getAddresses();
for(InetAddress iaddress:addresses){
if(!iaddress.getHostAddress().equals(stunService.getPrimaryAddress())){
%>
<option value="<%=iaddress.getHostAddress()%>"><%=iaddress.getHostAddress()%>
</option>
<%
}
}
String sname = JiveGlobals.getProperty("xmpp.domain", JiveGlobals.getXMLProperty("network.interface", "localhost"));
%>
<option value="<%=sname%>"><%=sname%>
</option>
</td>
<th nowrap align="left">
<fmt:message key="stun.external.server"/>
</th>
<th nowrap align="left">
<fmt:message key="stun.external.port"/>
</th>
<th nowrap align="left">
<fmt:message key="stun.external.delete"/>
</th>
</tr>
</thead>
<tbody>
<%
int i = 0;
for (STUNService.StunServerAddress stunServerAddress : stunService.getExternalServers()) {
%>
<tr>
<td align="left"> <fmt:message key="stun.settings.secondaryaddress" />:&nbsp<select size="1"
maxlength="100"
name="secondaryAddress"
align="left">
<option value="<%=stunService.getSecondaryAddress()%>"><%=stunService.getSecondaryAddress()%>
</option>
<%
for (InetAddress iaddress : addresses) {
if (!iaddress.getHostAddress().equals(stunService.getSecondaryAddress())) {
%>
<option value="<%=iaddress.getHostAddress()%>"><%=iaddress.getHostAddress()%>
</option>
<% }
}%>
<option value="127.0.0.1">127.0.0.1</option>
</select>
<td align="left">
<%=stunServerAddress.getServer()%>
</td>
<td align="left">
<%=stunServerAddress.getPort()%>
</td>
<td align="center">
<a href="#" onclick="document.add.remove.value=<%=i++%>;document.add.submit();">
<img src="images/delete-16x16.gif" width="16" height="16" border="0"
alt="<fmt:message key="global.click_delete" />">
</a>
</td>
</tr>
<%
}
%>
<input type="hidden" name="remove" value="">
<tr>
<td align="left"> <fmt:message key="stun.settings.primaryport" />:&nbsp<input type="text" size="20"
maxlength="100"
name="primaryPort"
value="<%=stunService.getPrimaryPort()%>"
align="left">
<td align="left">
<input type="text" name="externalServer" size="20" maxlength="50">
</td>
<td align="left">
<input type="text" name="externalPort" size="6" maxlength="6">
</td>
</tr>
<tr>
<td align="left"><fmt:message key="stun.settings.secondaryport" />:&nbsp<input type="text" size="20"
maxlength="100"
name="secondaryPort"
value="<%=stunService.getSecondaryPort()%>"
align="left">
<td>
&nbsp;
</td>
</tr>
<tr>
<td align="left"><fmt:message key="stun.settings.enabled" />:&nbsp<input type="checkbox"
name="enabled"
<%=stunService.isEnabled()?"checked":""%>
align="left">
<td>
<input type="submit" name="add" value="<fmt:message key="stun.external.add"/>">
</td>
</tr>
</tbody>
</table>
</div>
<input type="hidden" name="save">
<input type="button" name="set" value="<fmt:message key="stun.settings.change" />" onclick="checkAndSubmit()">
</form>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment