diff --git a/p2pproxy/launcher/.cproject b/p2pproxy/launcher/.cproject
index 8863ad35f..a6611c769 100644
--- a/p2pproxy/launcher/.cproject
+++ b/p2pproxy/launcher/.cproject
@@ -121,6 +121,7 @@
+
@@ -506,6 +507,7 @@
+
diff --git a/p2pproxy/launcher/Debug/makefile b/p2pproxy/launcher/Debug/makefile
index 9685c7609..9559e2f52 100644
--- a/p2pproxy/launcher/Debug/makefile
+++ b/p2pproxy/launcher/Debug/makefile
@@ -29,7 +29,7 @@ all: p2pproxy-launcher
p2pproxy-launcher: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C Linker'
- gcc -L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64 -L/usr/lib/jvm/java-6-openjdk/jre/lib/i386 -L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server -L/usr/lib/jvm/java-6-openjdk/jre/lib/i386/server -o"p2pproxy-launcher" $(OBJS) $(USER_OBJS) $(LIBS)
+ gcc -L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64 -L/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server -o"p2pproxy-launcher" $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '
diff --git a/p2pproxy/launcher/src/launcher-tester.c b/p2pproxy/launcher/src/launcher-tester.c
index 2f92ecddb..2d907c0eb 100644
--- a/p2pproxy/launcher/src/launcher-tester.c
+++ b/p2pproxy/launcher/src/launcher-tester.c
@@ -32,15 +32,27 @@ int main(int argc, char **argv) {
}
char string_buffer[256];
- if (p2pproxy_resourcelocation_get_sip_proxyregistrar_uri(string_buffer,256) != P2PPROXY_NO_ERROR) {
+ if (p2pproxy_resourcemgt_lookup_sip_proxy(string_buffer,256,"p2p.linphone.org") != P2PPROXY_NO_ERROR) {
printf("cannot get proxy\n");
} else {
printf("registrar is [%s]\n",string_buffer);
}
+
+ if (p2pproxy_resourcemgt_revoke_sip_proxy(string_buffer) != P2PPROXY_NO_ERROR) {
+ printf("cannot fulsh proxy [%s]\n",string_buffer);
+ }
+
+ if (p2pproxy_resourcemgt_lookup_sip_proxy(string_buffer,256,"toto.linphone.org") != P2PPROXY_RESOURCEMGT_SERVER_NOT_FOUND) {
+ printf("unexpected proxy [%s]\n",string_buffer);
+ } else {
+ printf("unknown domaine\n");
+ }
+
if (p2pproxy_accountmgt_deleteAccount("sip:titi@p2p.linphone.org") != P2PPROXY_NO_ERROR) {
printf("cannot delete account \n");
}
+
p2pproxy_application_stop();
pthread_join(th,NULL);
return 0;
diff --git a/p2pproxy/launcher/src/p2pproxy.c b/p2pproxy/launcher/src/p2pproxy.c
index da4dd5e75..cae324cb3 100644
--- a/p2pproxy/launcher/src/p2pproxy.c
+++ b/p2pproxy/launcher/src/p2pproxy.c
@@ -1,5 +1,6 @@
#include
#include
+#include
#include "p2pproxy.h"
#ifndef P2PPROXY_JMX_PORT
@@ -138,25 +139,43 @@ int p2pproxy_accountmgt_deleteAccount(const char* user_name) {
return lResult;
}
-int p2pproxy_resourcelocation_get_sip_proxyregistrar_uri(char* aStringArray, size_t aSize) {
- jmethodID getSipProxyRegistrarUriMethod;
+int p2pproxy_resourcemgt_lookup_sip_proxy(char* proxy_uri,size_t size, char* domaine) {
+ jmethodID lLookupSipProxyUriMethod;
jstring lJStringResult;
const jbyte* lString;
jboolean lIsCopy;
- GET_JNI_ENV
+ jstring applicationArg;
- getSipProxyRegistrarUriMethod = (*lJniEnv)->GetStaticMethodID(lJniEnv, lMainClass, "getSipProxyRegistrarUri", "()Ljava/lang/String;");
- lJStringResult = (*lJniEnv)->CallStaticObjectMethod(lJniEnv, lMainClass, getSipProxyRegistrarUriMethod);
+ GET_JNI_ENV
+
+
+ applicationArg = (*lJniEnv)->NewStringUTF(lJniEnv, domaine);
+ lLookupSipProxyUriMethod = (*lJniEnv)->GetStaticMethodID(lJniEnv, lMainClass, "lookupSipProxyUri", "(Ljava/lang/String;)Ljava/lang/String;");
+ lJStringResult = (*lJniEnv)->CallStaticObjectMethod(lJniEnv, lMainClass, lLookupSipProxyUriMethod, applicationArg);
if (lJStringResult == 0) {
- return P2PPROXY_ERROR_RESOURCELOCATOR_SERVER_NOT_FOUND;
+ return P2PPROXY_RESOURCEMGT_SERVER_NOT_FOUND;
}
lString = (*lJniEnv)->GetStringUTFChars(lJniEnv, lJStringResult, &lIsCopy);
- memcpy(aStringArray,lString,aSize);
+ memcpy(proxy_uri,lString,size);
(*lJniEnv)->ReleaseStringUTFChars(lJniEnv, lJStringResult, lString);
(*p2pproxy_application_jvm)->DetachCurrentThread(p2pproxy_application_jvm);
return P2PPROXY_NO_ERROR;
}
+int p2pproxy_resourcemgt_revoke_sip_proxy(char* proxy_uri) {
+ jmethodID revokeProxyMethod;
+ jstring lJStringResult;
+ const jbyte* lString;
+ jboolean lIsCopy;
+ GET_JNI_ENV
+
+ revokeProxyMethod = (*lJniEnv)->GetStaticMethodID(lJniEnv, lMainClass, "revokeSipProxy", "(Ljava/lang/String;)V");
+ (*lJniEnv)->CallStaticVoidMethod(lJniEnv, lMainClass, revokeProxyMethod);
+ if (lJStringResult == 0) {
+ return P2PPROXY_ERROR;
+ }
+ return P2PPROXY_NO_ERROR;
+}
int p2pproxy_application_get_state() {
jmethodID stateMethod;
GET_JNI_ENV
diff --git a/p2pproxy/launcher/src/p2pproxy.h b/p2pproxy/launcher/src/p2pproxy.h
index 08f6a4999..4ebb90596 100644
--- a/p2pproxy/launcher/src/p2pproxy.h
+++ b/p2pproxy/launcher/src/p2pproxy.h
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define P2PPROXY_ACCOUNTMGT_USER_EXIST 1
#define P2PPROXY_ACCOUNTMGT_USER_NOT_EXIST 0
-
+#define P2PPROXY_RESOURCEMGT_SERVER_NOT_FOUND 3
/* state code*/
#define P2PPROXY_CONNECTED 2
#define P2PPROXY_NOT_CONNECTED 1
@@ -41,7 +41,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define P2PPROXY_ERROR_APPLICATION_ALREADY_STARTED -3
#define P2PPROXY_ERROR_ACCOUNTMGT_USER_ALREADY_EXIST -4
#define P2PPROXY_ERROR_ACCOUNTMGT_BAD_SIP_URI -5
-#define P2PPROXY_ERROR_RESOURCELOCATOR_SERVER_NOT_FOUND -6
+#define P2PPROXY_ERROR_RESOURCEMGT_SERVER_NOT_FOUND -6
#ifndef SWIG
/**
@@ -97,16 +97,24 @@ int p2pproxy_accountmgt_isValidAccount(const char* user_name);
*/
int p2pproxy_accountmgt_deleteAccount(const char* user_name);
-/***************************/
-/***resource location******/
-/***************************/
+/****************************/
+/***resource management******/
+/****************************/
/**
-* access a proxy registrar sip addreess
-* @param buffer allocated by the user
-* @param size buffer size
+* access a proxy registrar sip addreess for a given domaine name
+* @param [out] proxy_uri buffer allocated by the user
+* @param [in] size buffer size
+* @param [in] domaine name
* @return status code P2PPROXY_NO_ERROR, P2PPROXY_ERROR_RESOURCELOCATOR_SERVER_NOT_FOUND
*/
-int p2pproxy_resourcelocation_get_sip_proxyregistrar_uri(char* string_buffer,size_t size) ;
+int p2pproxy_resourcemgt_lookup_sip_proxy(char* proxy_uri,size_t size, char* domaine) ;
+/*
+ * notify the library at a given proxy is no longuer reachable
+* @param [in] proxy sip uri
+* @return status code P2PPROXY_NO_ERROR
+*/
+int p2pproxy_resourcemgt_revoke_sip_proxy(char* proxy_uri);
+
#endif /*SWIG*/
diff --git a/p2pproxy/src/org/linphone/p2pproxy/api/P2pProxySipProxyRegistrarManagement.java b/p2pproxy/src/org/linphone/p2pproxy/api/P2pProxySipProxyRegistrarManagement.java
index 35e7d4d39..3de678773 100644
--- a/p2pproxy/src/org/linphone/p2pproxy/api/P2pProxySipProxyRegistrarManagement.java
+++ b/p2pproxy/src/org/linphone/p2pproxy/api/P2pProxySipProxyRegistrarManagement.java
@@ -19,12 +19,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.p2pproxy.api;
-import java.net.InetSocketAddress;
+
public interface P2pProxySipProxyRegistrarManagement {
/**
*
- * @return the SIP uri of an available sip proxy registrar
+ * @return the SIP uri of an available sip proxy registrar for a given domaine
*/
- public String getSipProxyRegistrarUri() throws P2pProxyException ;
+ public String lookupSipProxyUri(String aDomaine) throws P2pProxyException ;
+
+ public void revokeSipProxy(String aProxy) throws P2pProxyException;
+
}
diff --git a/p2pproxy/src/org/linphone/p2pproxy/core/JxtaNetworkManager.java b/p2pproxy/src/org/linphone/p2pproxy/core/JxtaNetworkManager.java
index 5210ba68c..2ab78ad39 100644
--- a/p2pproxy/src/org/linphone/p2pproxy/core/JxtaNetworkManager.java
+++ b/p2pproxy/src/org/linphone/p2pproxy/core/JxtaNetworkManager.java
@@ -136,7 +136,8 @@ public class JxtaNetworkManager {
} else {
lNetworkConfigurator.load();
}
-
+ //mode is alway taken from start line
+ lNetworkConfigurator.setMode(lMode);
// set sedding host
if (aProperties.getProperty(SEEDING_RDV) != null) {
StringTokenizer lSeedingRdvList = new StringTokenizer(aProperties.getProperty(SEEDING_RDV),"|" );
diff --git a/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java b/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java
index f1bca231c..906035a04 100644
--- a/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java
+++ b/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java
@@ -386,11 +386,10 @@ private static void isReady() throws P2pProxyNotReadyException {
try {
if ((mJxtaNetworkManager!=null && mJxtaNetworkManager.isConnectedToRendezVous(0) == true)
||
- (mJxtaNetworkManager!=null && mJxtaNetworkManager.getPeerGroup().getRendezVousService().isRendezVous()))
- {
+ (mJxtaNetworkManager!=null && mJxtaNetworkManager.getPeerGroup().getRendezVousService().isRendezVous())) {
//nop connected
} else {
- throw new P2pProxyNotReadyException("not connected to any rdv");
+ throw new P2pProxyNotReadyException("not connected to any rdv: status ["+mJxtaNetworkManager.getPeerGroup().getRendezVousService().getRendezVousStatus()+"]");
}
} catch (InterruptedException e) {
throw new P2pProxyNotReadyException(e);
@@ -431,10 +430,10 @@ public static int isValidAccount(String aUserName){
return P2pProxylauncherConstants.P2PPROXY_ERROR;
}
}
-public static String getSipProxyRegistrarUri() {
+public static String lookupSipProxyUri(String aDomaine) {
try {
isReady();
- return mP2pProxySipProxyRegistrarManagement.getSipProxyRegistrarUri();
+ return mP2pProxySipProxyRegistrarManagement.lookupSipProxyUri(aDomaine);
} catch (Exception e) {
return null;
}
@@ -444,9 +443,20 @@ public static int getState() {
isReady();
return P2pProxylauncherConstants.P2PPROXY_CONNECTED;
} catch (P2pProxyException e) {
+ mLog.error("cannot get state",e);
return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
}
}
+public static int revokeSipProxy(String aProxy) {
+ try {
+ isReady();
+ mLog.error("not implemented");
+ return P2pProxylauncherConstants.P2PPROXY_ERROR;
+ } catch (P2pProxyException e) {
+ return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
+ }
+}
+
public static void stop() {
mExit = true;
diff --git a/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxySipProxyRegistrarManagementImpl.java b/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxySipProxyRegistrarManagementImpl.java
index b1a15a3ad..5ef52d245 100644
--- a/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxySipProxyRegistrarManagementImpl.java
+++ b/p2pproxy/src/org/linphone/p2pproxy/core/P2pProxySipProxyRegistrarManagementImpl.java
@@ -1,22 +1,38 @@
package org.linphone.p2pproxy.core;
+import org.apache.log4j.Logger;
import org.linphone.p2pproxy.api.P2pProxyException;
import org.linphone.p2pproxy.api.P2pProxySipProxyRegistrarManagement;
import org.linphone.p2pproxy.core.sipproxy.SipProxyRegistrarAdvertisement;
public class P2pProxySipProxyRegistrarManagementImpl implements P2pProxySipProxyRegistrarManagement {
- protected final JxtaNetworkManager mJxtaNetworkManager;
- P2pProxySipProxyRegistrarManagementImpl(JxtaNetworkManager aJxtaNetworkManager) {
- mJxtaNetworkManager = aJxtaNetworkManager;
- }
- public String getSipProxyRegistrarUri() throws P2pProxyException {
- try {
- SipProxyRegistrarAdvertisement lSipProxyRegistrarAdvertisement = (SipProxyRegistrarAdvertisement) (mJxtaNetworkManager.getAdvertisement(null, SipProxyRegistrarAdvertisement.NAME, true));
- return lSipProxyRegistrarAdvertisement.getAddress();
- }catch (Exception e) {
- throw new P2pProxyException(e);
- }
+ protected final JxtaNetworkManager mJxtaNetworkManager;
+ private final String DOMAINE="p2p.linphone.org";
+ private final static Logger mLog = Logger.getLogger(P2pProxySipProxyRegistrarManagementImpl.class);
+ P2pProxySipProxyRegistrarManagementImpl(JxtaNetworkManager aJxtaNetworkManager) {
+ mJxtaNetworkManager = aJxtaNetworkManager;
+ }
+ public String lookupSipProxyUri(String aDomaine) throws P2pProxyException {
+ try {
+ if (!DOMAINE.equals(aDomaine)) {
+ //unknown domaine
+ return null;
+ }
+ SipProxyRegistrarAdvertisement lSipProxyRegistrarAdvertisement = (SipProxyRegistrarAdvertisement) (mJxtaNetworkManager.getAdvertisement(null, SipProxyRegistrarAdvertisement.NAME, true));
+ return lSipProxyRegistrarAdvertisement.getAddress();
+ }catch (Exception e) {
+ throw new P2pProxyException(e);
+ }
- }
+ }
+ public void revokeSipProxy(String aProxy) throws P2pProxyException {
+ try {
+ SipProxyRegistrarAdvertisement lSipProxyRegistrarAdvertisement = (SipProxyRegistrarAdvertisement) (mJxtaNetworkManager.getAdvertisement(null, SipProxyRegistrarAdvertisement.ADDRESS_TAG, true));
+ mJxtaNetworkManager.getPeerGroup().getDiscoveryService().flushAdvertisement(lSipProxyRegistrarAdvertisement);
+ mLog.info(aProxy +"revoked");
+ } catch (Exception e) {
+ throw new P2pProxyException(e);
+ }
+ }
}
diff --git a/p2pproxy/src/org/linphone/p2pproxy/core/stun/StunServer.java b/p2pproxy/src/org/linphone/p2pproxy/core/stun/StunServer.java
new file mode 100644
index 000000000..ccbfaabc6
--- /dev/null
+++ b/p2pproxy/src/org/linphone/p2pproxy/core/stun/StunServer.java
@@ -0,0 +1,184 @@
+/*
+ * This file is part of JSTUN.
+ *
+ * Copyright (c) 2005 Thomas King - All rights
+ * reserved.
+ *
+ * This software is licensed under either the GNU Public License (GPL),
+ * or the Apache 2.0 license. Copies of both license agreements are
+ * included in this distribution.
+ */
+
+package org.linphone.p2pproxy.core.stun;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Vector;
+import java.util.logging.FileHandler;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.logging.SimpleFormatter;
+
+import de.javawi.jstun.attribute.ChangeRequest;
+import de.javawi.jstun.attribute.ChangedAddress;
+import de.javawi.jstun.attribute.MappedAddress;
+import de.javawi.jstun.attribute.MessageAttributeException;
+import de.javawi.jstun.attribute.MessageAttributeParsingException;
+import de.javawi.jstun.attribute.ResponseAddress;
+import de.javawi.jstun.attribute.SourceAddress;
+import de.javawi.jstun.attribute.UnknownAttribute;
+import de.javawi.jstun.attribute.UnknownMessageAttributeException;
+import de.javawi.jstun.attribute.MessageAttributeInterface.MessageAttributeType;
+import de.javawi.jstun.header.MessageHeader;
+import de.javawi.jstun.header.MessageHeaderParsingException;
+import de.javawi.jstun.header.MessageHeaderInterface.MessageHeaderType;
+import de.javawi.jstun.util.Address;
+import de.javawi.jstun.util.UtilityException;
+
+/*
+ * This class implements a STUN server as described in RFC 3489.
+ * The server requires a machine that is dual-homed to be functional.
+ */
+public class StunServer {
+ private static Logger logger = Logger.getLogger("org.linphone.p2pproxy.core.stun.StunServer");
+ Vector sockets;
+
+ public StunServer(int primaryPort, InetAddress primary, int secondaryPort) throws SocketException {
+ sockets = new Vector();
+ sockets.add(new DatagramSocket(primaryPort, primary));
+ sockets.add(new DatagramSocket(secondaryPort, primary));
+ }
+
+ public void start() throws SocketException {
+ for (DatagramSocket socket : sockets) {
+ socket.setReceiveBufferSize(2000);
+ StunServerReceiverThread ssrt = new StunServerReceiverThread(socket);
+ ssrt.start();
+ }
+ }
+
+ /*
+ * Inner class to handle incoming packets and react accordingly.
+ * I decided not to start a thread for every received Binding Request, because the time
+ * required to receive a Binding Request, parse it, generate a Binding Response and send
+ * it varies only between 2 and 4 milliseconds. This amount of time is small enough so
+ * that no extra thread is needed for incoming Binding Request.
+ */
+ class StunServerReceiverThread extends Thread {
+ private DatagramSocket receiverSocket;
+ private DatagramSocket changedPort;
+
+ StunServerReceiverThread(DatagramSocket datagramSocket) {
+ this.receiverSocket = datagramSocket;
+ for (DatagramSocket socket : sockets) {
+ if ((socket.getLocalPort() != receiverSocket.getLocalPort()) &&
+ (socket.getLocalAddress().equals(receiverSocket.getLocalAddress())))
+ changedPort = socket;
+ }
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ DatagramPacket receive = new DatagramPacket(new byte[200], 200);
+ receiverSocket.receive(receive);
+ logger.finest(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " datagram received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort());
+ MessageHeader receiveMH = MessageHeader.parseHeader(receive.getData());
+ try {
+ receiveMH.parseAttributes(receive.getData());
+ if (receiveMH.getType() == MessageHeaderType.BindingRequest) {
+ logger.config(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " Binding Request received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort());
+ ChangeRequest cr = (ChangeRequest) receiveMH.getMessageAttribute(MessageAttributeType.ChangeRequest);
+ if (cr == null) throw new MessageAttributeException("Message attribute change request is not set.");
+ ResponseAddress ra = (ResponseAddress) receiveMH.getMessageAttribute(MessageAttributeType.ResponseAddress);
+
+ MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingResponse);
+ sendMH.setTransactionID(receiveMH.getTransactionID());
+
+ // Mapped address attribute
+ MappedAddress ma = new MappedAddress();
+ ma.setAddress(new Address(receive.getAddress().getAddress()));
+ ma.setPort(receive.getPort());
+ sendMH.addMessageAttribute(ma);
+ if (cr.isChangePort()) {
+ logger.finer("Change port received in Change Request attribute");
+ // Source address attribute
+ SourceAddress sa = new SourceAddress();
+ sa.setAddress(new Address(changedPort.getLocalAddress().getAddress()));
+ sa.setPort(changedPort.getLocalPort());
+ sendMH.addMessageAttribute(sa);
+ byte[] data = sendMH.getBytes();
+ DatagramPacket send = new DatagramPacket(data, data.length);
+ if (ra != null) {
+ send.setPort(ra.getPort());
+ send.setAddress(ra.getAddress().getInetAddress());
+ } else {
+ send.setPort(receive.getPort());
+ send.setAddress(receive.getAddress());
+ }
+ changedPort.send(send);
+ logger.config(changedPort.getLocalAddress().getHostAddress() + ":" + changedPort.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
+ } else if ((!cr.isChangePort()) && (!cr.isChangeIP())) {
+ logger.finer("Nothing received in Change Request attribute");
+ // Source address attribute
+ SourceAddress sa = new SourceAddress();
+ sa.setAddress(new Address(receiverSocket.getLocalAddress().getAddress()));
+ sa.setPort(receiverSocket.getLocalPort());
+ sendMH.addMessageAttribute(sa);
+ byte[] data = sendMH.getBytes();
+ DatagramPacket send = new DatagramPacket(data, data.length);
+ if (ra != null) {
+ send.setPort(ra.getPort());
+ send.setAddress(ra.getAddress().getInetAddress());
+ } else {
+ send.setPort(receive.getPort());
+ send.setAddress(receive.getAddress());
+ }
+ receiverSocket.send(send);
+ logger.config(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
+ } else {
+ logger.warning("cannot handle cr ["+cr+"]");
+ }
+ }
+ } catch (UnknownMessageAttributeException umae) {
+ umae.printStackTrace();
+ // Generate Binding error response
+ MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingErrorResponse);
+ sendMH.setTransactionID(receiveMH.getTransactionID());
+
+ // Unknown attributes
+ UnknownAttribute ua = new UnknownAttribute();
+ ua.addAttribute(umae.getType());
+ sendMH.addMessageAttribute(ua);
+
+ byte[] data = sendMH.getBytes();
+ DatagramPacket send = new DatagramPacket(data, data.length);
+ send.setPort(receive.getPort());
+ send.setAddress(receive.getAddress());
+ receiverSocket.send(send);
+ logger.config(" send Binding Error Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } catch (MessageAttributeParsingException mape) {
+ mape.printStackTrace();
+ } catch (MessageAttributeException mae) {
+ mae.printStackTrace();
+ } catch (MessageHeaderParsingException mhpe) {
+ mhpe.printStackTrace();
+ } catch (UtilityException ue) {
+ ue.printStackTrace();
+ } catch (ArrayIndexOutOfBoundsException aioobe) {
+ aioobe.printStackTrace();
+ }
+ }
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/p2pproxy/src/org/linphone/p2pproxy/core/turnserver/TurnServer.java b/p2pproxy/src/org/linphone/p2pproxy/core/turnserver/TurnServer.java
deleted file mode 100644
index 1931afec9..000000000
--- a/p2pproxy/src/org/linphone/p2pproxy/core/turnserver/TurnServer.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * This file is part of JSTUN.
- *
- * Copyright (c) 2005 Thomas King - All rights
- * reserved.
- *
- * This software is licensed under either the GNU Public License (GPL),
- * or the Apache 2.0 license. Copies of both license agreements are
- * included in this distribution.
- */
-
-package org.linphone.p2pproxy.core.turnserver;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.util.Vector;
-
-import org.apache.log4j.BasicConfigurator;
-import org.apache.log4j.Logger;
-
-
-import de.javawi.jstun.attribute.ChangeRequest;
-import de.javawi.jstun.attribute.ChangedAddress;
-import de.javawi.jstun.attribute.MappedAddress;
-import de.javawi.jstun.attribute.MessageAttributeException;
-import de.javawi.jstun.attribute.MessageAttributeParsingException;
-import de.javawi.jstun.attribute.ResponseAddress;
-import de.javawi.jstun.attribute.SourceAddress;
-import de.javawi.jstun.attribute.UnknownAttribute;
-import de.javawi.jstun.attribute.UnknownMessageAttributeException;
-import de.javawi.jstun.attribute.MessageAttributeInterface.MessageAttributeType;
-import de.javawi.jstun.header.MessageHeader;
-import de.javawi.jstun.header.MessageHeaderParsingException;
-import de.javawi.jstun.header.MessageHeaderInterface.MessageHeaderType;
-import de.javawi.jstun.util.Address;
-import de.javawi.jstun.util.UtilityException;
-
-/*
- * This class implements a STUN server as described in RFC 3489.
- * The server requires a machine that is dual-homed to be functional.
- * This implementation uses a single ip/port. This lead to limited functionnality.
- */
-public class TurnServer {
- private static Logger logger = Logger.getLogger(TurnServer.class);
- Vector sockets;
-
- public TurnServer(int primaryPort, InetAddress primary) throws SocketException {
- sockets = new Vector();
- sockets.add(new DatagramSocket(primaryPort, primary));
- }
-
- public TurnServer(int primaryPort, InetAddress primary, int secondaryPort, InetAddress secondary) throws SocketException {
- sockets = new Vector();
- sockets.add(new DatagramSocket(primaryPort, primary));
- //sockets.add(new DatagramSocket(secondaryPort, primary));
- //sockets.add(new DatagramSocket(primaryPort, secondary));
- //sockets.add(new DatagramSocket(secondaryPort, secondary));
- }
-
- public void start() throws SocketException {
- for (DatagramSocket socket : sockets) {
- socket.setReceiveBufferSize(2000);
- StunServerReceiverThread ssrt = new StunServerReceiverThread(socket);
- ssrt.start();
- }
- }
-
- /*
- * Inner class to handle incoming packets and react accordingly.
- * I decided not to start a thread for every received Binding Request, because the time
- * required to receive a Binding Request, parse it, generate a Binding Response and send
- * it varies only between 2 and 4 milliseconds. This amount of time is small enough so
- * that no extra thread is needed for incoming Binding Request.
- */
- class StunServerReceiverThread extends Thread {
- private DatagramSocket receiverSocket;
- private DatagramSocket changedPort;
- private DatagramSocket changedIP;
- private DatagramSocket changedPortIP;
-
- StunServerReceiverThread(DatagramSocket datagramSocket) {
- this.receiverSocket = datagramSocket;
- for (DatagramSocket socket : sockets) {
- if ((socket.getLocalPort() != receiverSocket.getLocalPort()) &&
- (socket.getLocalAddress().equals(receiverSocket.getLocalAddress())))
- changedPort = socket;
- if ((socket.getLocalPort() == receiverSocket.getLocalPort()) &&
- (!socket.getLocalAddress().equals(receiverSocket.getLocalAddress())))
- changedIP = socket;
- if ((socket.getLocalPort() != receiverSocket.getLocalPort()) &&
- (!socket.getLocalAddress().equals(receiverSocket.getLocalAddress())))
- changedPortIP = socket;
- }
- }
-
- public void run() {
- while (true) {
- try {
- DatagramPacket receive = new DatagramPacket(new byte[200], 200);
- receiverSocket.receive(receive);
- logger.debug(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " datagram received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort());
- MessageHeader receiveMH = MessageHeader.parseHeader(receive.getData());
- try {
- receiveMH.parseAttributes(receive.getData());
- logger.info(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " Request received from " + receive.getAddress().getHostAddress() + ":" + receive.getPort());
-
- if (receiveMH.getType() == MessageHeaderType.BindingRequest) {
- logger.info("Binding Request received ");
- ChangeRequest cr = (ChangeRequest) receiveMH.getMessageAttribute(MessageAttributeType.ChangeRequest);
- if (cr == null) throw new MessageAttributeException("Message attribute change request is not set.");
- ResponseAddress ra = (ResponseAddress) receiveMH.getMessageAttribute(MessageAttributeType.ResponseAddress);
-
- MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingResponse);
- sendMH.setTransactionID(receiveMH.getTransactionID());
-
- // Mapped address attribute
- MappedAddress ma = new MappedAddress();
- ma.setAddress(new Address(receive.getAddress().getAddress()));
- ma.setPort(receive.getPort());
- sendMH.addMessageAttribute(ma);
- // Changed address attribute
- //ChangedAddress ca = new ChangedAddress();
- //ca.setAddress(new Address(changedPortIP.getLocalAddress().getAddress()));
- //ca.setPort(changedPortIP.getLocalPort());
- //sendMH.addMessageAttribute(ca);
- if (cr.isChangePort() && (!cr.isChangeIP())) {
- logger.info("Change port received in Change Request attribute");
- // Source address attribute
- SourceAddress sa = new SourceAddress();
- sa.setAddress(new Address(changedPort.getLocalAddress().getAddress()));
- sa.setPort(changedPort.getLocalPort());
- sendMH.addMessageAttribute(sa);
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- if (ra != null) {
- send.setPort(ra.getPort());
- send.setAddress(ra.getAddress().getInetAddress());
- } else {
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- }
- changedPort.send(send);
- logger.info(changedPort.getLocalAddress().getHostAddress() + ":" + changedPort.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- } else if ((!cr.isChangePort()) && cr.isChangeIP()) {
- logger.info("Change ip received in Change Request attribute");
- // Source address attribute
- SourceAddress sa = new SourceAddress();
- sa.setAddress(new Address(changedIP.getLocalAddress().getAddress()));
- sa.setPort(changedIP.getLocalPort());
- sendMH.addMessageAttribute(sa);
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- if (ra != null) {
- send.setPort(ra.getPort());
- send.setAddress(ra.getAddress().getInetAddress());
- } else {
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- }
- changedIP.send(send);
- logger.info(changedIP.getLocalAddress().getHostAddress() + ":" + changedIP.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- } else if ((!cr.isChangePort()) && (!cr.isChangeIP())) {
- logger.info("Nothing received in Change Request attribute");
- // Source address attribute
- SourceAddress sa = new SourceAddress();
- sa.setAddress(new Address(receiverSocket.getLocalAddress().getAddress()));
- sa.setPort(receiverSocket.getLocalPort());
- sendMH.addMessageAttribute(sa);
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- if (ra != null) {
- send.setPort(ra.getPort());
- send.setAddress(ra.getAddress().getInetAddress());
- } else {
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- }
- receiverSocket.send(send);
- logger.info(receiverSocket.getLocalAddress().getHostAddress() + ":" + receiverSocket.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- } else if (cr.isChangePort() && cr.isChangeIP()) {
- logger.info("Change port and ip received in Change Request attribute");
- // Source address attribute
- SourceAddress sa = new SourceAddress();
- sa.setAddress(new Address(changedPortIP.getLocalAddress().getAddress()));
- sa.setPort(changedPortIP.getLocalPort());
- sendMH.addMessageAttribute(sa);
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- if (ra != null) {
- send.setPort(ra.getPort());
- send.setAddress(ra.getAddress().getInetAddress());
- } else {
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- }
- changedPortIP.send(send);
- logger.info(changedPortIP.getLocalAddress().getHostAddress() + ":" + changedPortIP.getLocalPort() + " send Binding Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- }
- } else if (receiveMH.getType() == MessageHeaderType.AllocateRequest) {
- logger.info("Allocate Request received ");
- MessageHeader sendMH = new MessageHeader(MessageHeaderType.AllocateResponse);
- sendMH.setTransactionID(receiveMH.getTransactionID());
-
-
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- receiverSocket.send(send);
- logger.info( "Send Allocate Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- }
- } catch (UnknownMessageAttributeException umae) {
- umae.printStackTrace();
- // Generate Binding error response
- MessageHeader sendMH = new MessageHeader(MessageHeaderType.BindingErrorResponse);
- sendMH.setTransactionID(receiveMH.getTransactionID());
-
- // Unknown attributes
- UnknownAttribute ua = new UnknownAttribute();
- ua.addAttribute(umae.getType());
- sendMH.addMessageAttribute(ua);
-
- byte[] data = sendMH.getBytes();
- DatagramPacket send = new DatagramPacket(data, data.length);
- send.setPort(receive.getPort());
- send.setAddress(receive.getAddress());
- receiverSocket.send(send);
- logger.info(changedPortIP.getLocalAddress().getHostAddress() + ":" + changedPortIP.getLocalPort() + " send Binding Error Response to " + send.getAddress().getHostAddress() + ":" + send.getPort());
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } catch (MessageAttributeParsingException mape) {
- mape.printStackTrace();
- } catch (MessageAttributeException mae) {
- mae.printStackTrace();
- } catch (MessageHeaderParsingException mhpe) {
- mhpe.printStackTrace();
- } catch (UtilityException ue) {
- ue.printStackTrace();
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- aioobe.printStackTrace();
- }
- }
- }
- }
-
- /*
- * To invoke the STUN server two IP addresses and two ports are required.
- */
- public static void main(String args[]) {
- try {
- if (args.length != 4) {
- System.out.println("usage: java de.javawi.jstun.test.demo.StunServer PORT1 IP1 PORT2 IP2");
- System.out.println();
- System.out.println(" PORT1 - the first port that should be used by the server");
- System.out.println(" IP1 - the first ip address that should be used by the server");
- System.out.println(" PORT2 - the second port that should be used by the server");
- System.out.println(" IP2 - the second ip address that should be used by the server");
- System.exit(0);
- }
- BasicConfigurator.configure();
- TurnServer ss = new TurnServer(Integer.parseInt(args[0]),
- InetAddress.getByName(args[1]),
- Integer.parseInt(args[2]),
- InetAddress.getByName(args[3]));
- ss.start();
- } catch (SocketException se) {
- se.printStackTrace();
- } catch (UnknownHostException uhe) {
- uhe.printStackTrace();
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
-}
\ No newline at end of file
diff --git a/p2pproxy/test-src/org/linphone/p2pproxy/test/TurnServerTester.java b/p2pproxy/test-src/org/linphone/p2pproxy/test/StunServerTester.java
similarity index 98%
rename from p2pproxy/test-src/org/linphone/p2pproxy/test/TurnServerTester.java
rename to p2pproxy/test-src/org/linphone/p2pproxy/test/StunServerTester.java
index d69bc7ae0..cdad2983c 100644
--- a/p2pproxy/test-src/org/linphone/p2pproxy/test/TurnServerTester.java
+++ b/p2pproxy/test-src/org/linphone/p2pproxy/test/StunServerTester.java
@@ -25,7 +25,8 @@ import junit.framework.TestCase;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
-import org.linphone.p2pproxy.core.turnserver.TurnServer;
+import org.linphone.p2pproxy.core.stun.StunServer;
+
import de.javawi.jstun.attribute.ChangeRequest;
@@ -40,8 +41,8 @@ import de.javawi.jstun.header.MessageHeaderParsingException;
import de.javawi.jstun.test.DiscoveryInfo;
import de.javawi.jstun.util.UtilityException;
-public class TurnServerTester extends TestCase {
- private static Logger logger = Logger.getLogger(TurnServerTester.class);
+public class StunServerTester extends TestCase {
+ private static Logger logger = Logger.getLogger(StunServerTester.class);
InetAddress iaddress ;
String stunServer = "localhost";
int port = 16000;
@@ -51,14 +52,14 @@ public class TurnServerTester extends TestCase {
boolean nodeNatted = true;
DatagramSocket socketTest1 = null;
DiscoveryInfo di = null;
- static TurnServer mSturServer = null;
+ static StunServer mSturServer = null;
public void setUp() throws Exception {
if (mSturServer == null) {
BasicConfigurator.configure();
- if (mSturServer == null) mSturServer = new TurnServer(port,InetAddress.getByName("localhost"));
+ if (mSturServer == null) mSturServer = new StunServer(port,InetAddress.getByName("localhost"),port+1);
mSturServer.start();
iaddress = InetAddress.getLocalHost();
}