2 p2pproxy Copyright (C) 2007 Jehan Monnier ()
4 P2pProxyMain.java - main class.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package org.linphone.p2pproxy.core;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
30 import java.lang.management.ManagementFactory;
31 import java.util.InvalidPropertiesFormatException;
32 import java.util.Properties;
33 import java.util.concurrent.Callable;
34 import java.util.concurrent.Future;
36 import javax.management.ObjectName;
38 import net.jxta.exception.JxtaException;
39 import org.apache.log4j.Logger;
40 import org.apache.log4j.PropertyConfigurator;
41 import org.linphone.p2pproxy.api.P2pProxyException;
42 import org.linphone.p2pproxy.api.P2pProxyManagement;
43 import org.linphone.p2pproxy.api.P2pProxyNotReadyException;
44 import org.linphone.p2pproxy.api.P2pProxyResourceManagement;
45 import org.linphone.p2pproxy.api.P2pProxyUserAlreadyExistException;
46 import org.linphone.p2pproxy.core.media.MediaResourceService;
47 import org.linphone.p2pproxy.core.sipproxy.SipProxyRegistrar;
48 import org.linphone.p2pproxy.core.utils.Excecutor;
49 import org.zoolu.sip.provider.SipStack;
50 import org.linphone.p2pproxy.launcher.P2pProxylauncherConstants;
52 public class P2pProxyMain implements P2pProxyMainMBean {
53 private static Logger mLog = null;
54 private static JxtaNetworkManager mJxtaNetworkManager;
55 private static ServiceProvider mServiceProvider;
56 private static P2pProxyManagement mP2pProxyManagement;
57 private static SipProxyRegistrar mSipAndPipeListener;
58 private static P2pProxyAccountManagementMBean mP2pProxyAccountManagement;
59 private static P2pProxyResourceManagement mP2pProxySipProxyRegistrarManagement;
60 public final static String ACCOUNT_MGR_MBEAN_NAME="org.linphone.p2proxy:type=account-manager";
61 public final static String PROXY_REG_MBEAN_NAME="org.linphone.p2proxy:type=proxy-registrar";
62 public final static String MAIN_MBEAN_NAME="org.linphone.p2proxy:type=main";
63 private static P2pProxyMain mP2pProxyMain = new P2pProxyMain();
64 private static Configurator mConfigurator;
65 private static String mConfigHomeDir;
66 static private boolean mExit = false;
67 static private boolean isReady = false;
72 // System.setProperty("com.sun.management.jmxremote", "true");
73 // System.setProperty("com.sun.management.jmxremote.port", "6789");
74 // System.setProperty("com.sun.management.jmxremote.authenticate", "false");
75 // System.setProperty("com.sun.management.jmxremote.ssl", "false");
80 * @throws P2pProxyException
81 * @throws InterruptedException
82 * @throws JxtaException
84 * @throws FileNotFoundException
85 * @throws InvalidPropertiesFormatException
87 public static void main(String[] args) {
89 mConfigHomeDir=System.getProperty("user.home")+"/.p2pproxy";
91 int lMediaPort=MediaResourceService.AUDIO_VIDEO_LOCAL_PORT_DEFAULT_VALUE;
93 JxtaNetworkManager.Mode lMode = JxtaNetworkManager.Mode.auto;
96 // get config dire first
97 for (int i=0; i < args.length; i=i+2) {
98 String argument = args[i];
99 if (argument.equals("-jxta")) {
100 mConfigHomeDir = args[i + 1];
101 File lFile = new File(mConfigHomeDir);
102 if (lFile.exists() == false) lFile.mkdir();
104 System.out.println("mConfigHomeDir detected[" + mConfigHomeDir + "]");
107 System.setProperty("org.linphone.p2pproxy.home", mConfigHomeDir);
110 System.setProperty("net.jxta.logging.Logging", "FINEST");
111 System.setProperty("net.jxta.level", "FINEST");
113 mP2pProxyMain.loadTraceConfigFile();
117 mLog.info("p2pproxy initilizing...");
119 File lPropertyFile = new File(mConfigHomeDir+"/p2pproxy.properties.xml");
120 mConfigurator = new Configurator(lPropertyFile);
122 ObjectName lObjectName = new ObjectName(MAIN_MBEAN_NAME);
123 ManagementFactory.getPlatformMBeanServer().registerMBean(mP2pProxyMain,lObjectName);
126 } catch (Exception e) {
127 mLog.warn("cannot register MBean",e);
131 for (int i=0; i < args.length; i=i+2) {
132 String argument = args[i];
133 if (argument.equals("-jxta") || argument.equals("-home")) {
134 mConfigHomeDir = args[i + 1];
136 } else if (argument.equals("-sip")) {
137 lsipPort = Integer.parseInt(args[i + 1]);
138 System.out.println("sipPort detected[" + lsipPort + "]");
139 mConfigurator.setProperty(SipProxyRegistrar.REGISTRAR_PORT, Integer.toString(lsipPort));
140 } else if (argument.equals("-media")) {
141 lMediaPort = Integer.parseInt(args[i + 1]);
142 System.out.println("media detected[" + lMediaPort + "]");
143 mConfigurator.setProperty(MediaResourceService.AUDIO_VIDEO_LOCAL_PORT, Integer.toString(lMediaPort));
144 } else if (argument.equals("-p2p")) {
145 lP2pPort = Integer.parseInt(args[i + 1]);
146 System.out.println("p2p port detected[" + lP2pPort + "]");
147 mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PORT, Integer.toString(lP2pPort));
148 } else if (argument.equals("-relay")) {
149 lMode = JxtaNetworkManager.Mode.relay;
150 mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
151 System.out.println("relay mode detected");
153 } else if (argument.equals("-edge-only")) {
154 lMode = JxtaNetworkManager.Mode.edge;
155 mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
156 System.out.println("edge only mode detected");
158 }else if (argument.equals("-seeding-server")) {
159 lMode = JxtaNetworkManager.Mode.seeding_server;
160 mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
161 System.out.println("seeding-server detected");
163 } else if (argument.equals("-auto-config")) {
164 lMode = JxtaNetworkManager.Mode.auto;
165 mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
166 System.out.println("auto-mode mode detected");
168 } else if (argument.equals("-seeding-rdv")) {
169 mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RDV, args[i + 1]);
170 System.out.println("seeding rdv detected[" + args[i + 1] + "]");
172 else if (argument.equals("-seeding-relay")) {
173 mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RELAY, args[i + 1]);
174 System.out.println("seeding relay detected[" + args[i + 1] + "]");
175 } else if (argument.equals("-seeding")) {
176 mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RDV, args[i + 1]);
177 mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RELAY, args[i + 1]);
178 System.out.println("seeding detected[" + args[i + 1] + "]");
180 else if (argument.equals("-public-address")) {
181 mConfigurator.setProperty(JxtaNetworkManager.HTTP_LISTENING_PUBLIC_ADDRESS,args[i + 1]+":9700");
182 mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PUBLIC_ADDRESS,args[i + 1]+":"+lP2pPort);
183 mConfigurator.setProperty(MediaResourceService.AUDIO_VIDEO_PUBLIC_URI,"udp://"+args[i + 1]+":"+lMediaPort);
184 mConfigurator.setProperty(SipProxyRegistrar.REGISTRAR_PUBLIC_ADDRESS,args[i + 1]);
185 System.out.println("public address detected[" + args[i + 1] + "]");
189 System.out.println("Invalid option: " + args[i]);
195 File lJxtaDirectory = new File (mConfigHomeDir);
196 if (lJxtaDirectory.exists() == false) lJxtaDirectory.mkdir();
201 startEdge(mConfigurator,lJxtaDirectory);
204 startRelay(mConfigurator,lJxtaDirectory);
207 startSeeding(mConfigurator,lJxtaDirectory);
211 startEdge(mConfigurator,lJxtaDirectory);
212 // check if peer mode required
213 if (mP2pProxyManagement.shouldIBehaveAsAnRdv() == true) {
214 String lPublicAddress = mP2pProxyManagement.getPublicIpAddress().getHostAddress();
215 mConfigurator.setProperty(JxtaNetworkManager.HTTP_LISTENING_PUBLIC_ADDRESS, lPublicAddress+":9700");
216 mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PUBLIC_ADDRESS, lPublicAddress+":9701");
217 mServiceProvider.stop();
218 mJxtaNetworkManager.stop();
219 startRelay(mConfigurator,lJxtaDirectory);
220 mJxtaNetworkManager.getPeerGroup().getRendezVousService().setAutoStart(true);
224 mLog.fatal("unsupported mode ["+lMode+"]");
232 ObjectName lObjectName = new ObjectName(ACCOUNT_MGR_MBEAN_NAME);
233 ManagementFactory.getPlatformMBeanServer().registerMBean(mP2pProxyAccountManagement,lObjectName);
234 } catch (Exception e) {
235 mLog.warn("cannot register MBean",e);
239 mLog.warn("p2pproxy initilized");
241 while (mExit == false) {
244 if (mServiceProvider!= null) mServiceProvider.stop();
245 if (mServiceProvider!= null) mServiceProvider.stop();
246 if (mSipAndPipeListener!= null) mSipAndPipeListener.stop();
247 if (mJxtaNetworkManager != null) mJxtaNetworkManager.stop();
248 mLog.info("p2pproxy stopped");
251 } catch (Exception e) {
252 mLog.fatal("error",e);
256 private static void startEdge(Configurator aProperties,File aConfigDir) throws Exception{
258 mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
259 mServiceProvider = new EdgePeerServiceManager(aProperties, mJxtaNetworkManager);
260 mP2pProxyManagement = (P2pProxyManagement) mServiceProvider;
261 mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
262 //setup account manager
263 mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
264 mServiceProvider.start(3000L);
267 private static void startRelay(Configurator aProperties,File aConfigDir) throws Exception{
269 mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
270 mServiceProvider = new SuperPeerServiceManager(aProperties, mJxtaNetworkManager);
271 mP2pProxyManagement = (P2pProxyManagement) mServiceProvider;
272 mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
273 mServiceProvider.start(3000L);
274 //setup account manager
275 mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
276 // setup sip provider
277 SipStack.log_path = mConfigHomeDir+"/logs";
278 mSipAndPipeListener = new SipProxyRegistrar(mConfigurator,mJxtaNetworkManager,mP2pProxyAccountManagement);
281 ObjectName lObjectName = new ObjectName(PROXY_REG_MBEAN_NAME);
282 ManagementFactory.getPlatformMBeanServer().registerMBean(mSipAndPipeListener,lObjectName);
284 } catch (Exception e) {
285 mLog.warn("cannot register MBean",e);
288 private static void startSeeding(Configurator aProperties,File aConfigDir) throws Exception{
290 mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
291 mServiceProvider = new SeedingPeerServiceManager(aProperties, mJxtaNetworkManager,true);
292 mP2pProxyManagement = null;
293 mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
294 mServiceProvider.start(3000L);
295 //setup account manager
296 mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
297 // setup sip provider
298 SipStack.log_path = mConfigHomeDir+"/logs";
299 mSipAndPipeListener = new SipProxyRegistrar(mConfigurator,mJxtaNetworkManager,mP2pProxyAccountManagement);
302 ObjectName lObjectName = new ObjectName(PROXY_REG_MBEAN_NAME);
303 ManagementFactory.getPlatformMBeanServer().registerMBean(mSipAndPipeListener,lObjectName);
305 } catch (Exception e) {
306 mLog.warn("cannot register MBean",e);
309 private static void usage() {
310 System.out.println("p2pproxy");
311 System.out.println("-home : directory where configuration/cache is located (including jxta cache.default is $HOME/.p2pproxy");
312 System.out.println("-sip : udp proxy port, default 5060");
313 System.out.println("-media : udp relay/stun port, default 16000");
314 System.out.println("-p2p : p2p tcp port, default 9701");
315 System.out.println("-relay : super peer mode");
316 System.out.println("-edge-only : edge mode");
317 System.out.println("-seeding-server : seeding server mode");
318 System.out.println("-auto-config : automatically choose edge or relay (default mode)");
319 System.out.println("-seeding : list of boostrap rdv separated by | (ex tcp://127.0.0.1:9701|http://127.0.0.2:9700)");
320 System.out.println("-public-address : ip as exported to peers (ex myPublicAddress.no-ip.org)");
323 public void loadTraceConfigFile() throws P2pProxyException {
324 staticLoadTraceConfigFile();
326 public static void staticLoadTraceConfigFile() throws P2pProxyException {
328 InputStream lLog4jStream = null;
331 lSearchDir = System.getProperty("org.linphone.p2pproxy.build.dir");
332 File lFile = new File(lSearchDir+"/log4j.properties");
333 if (lFile.exists() == false) {
334 lSearchDir = mConfigHomeDir;
335 lFile = new File(lSearchDir+"/log4j.properties");
336 if (lFile.exists() == false) {
338 lFile = new File(lSearchDir+"/log4j.properties");
339 if (lFile.exists() == false) {
340 lLog4jStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("log4j.properties");
345 if (lLog4jStream == null) {
346 lLog4jStream = new FileInputStream(lFile);
348 Properties llog4Properties = new Properties();
349 llog4Properties.load(lLog4jStream);
350 PropertyConfigurator.configure(llog4Properties);
351 mLog = Logger.getLogger(P2pProxyMain.class);
352 // read java.util.logging properties
354 llog4Properties.setProperty("java.util.logging.FileHandler.pattern",System.getProperty("org.linphone.p2pproxy.home")+"/logs/p2pproxy.log");
355 File lLogConfigFile = new File(mConfigHomeDir.concat("log4j.properties")+".tmp");
356 if (lLogConfigFile.exists() == false) {
357 lLogConfigFile.createNewFile();
359 llog4Properties.store(new FileOutputStream(lLogConfigFile), "tmp");
360 System.setProperty("java.util.logging.config.file",lLogConfigFile.getAbsolutePath());
361 java.util.logging.LogManager.getLogManager().readConfiguration();
362 } catch (Exception e) {
363 throw new P2pProxyException("enable to load traces",e);
366 private static boolean isReadyNoThrow() {
370 } catch (P2pProxyNotReadyException e) {
374 private static void isReady() throws P2pProxyNotReadyException {
376 if ((isReady == true && mJxtaNetworkManager.isConnectedToRendezVous(0) == true)
378 (isReady == true && mJxtaNetworkManager.getPeerGroup().getRendezVousService().isRendezVous())) {
381 if (mJxtaNetworkManager != null ) {
382 throw new P2pProxyNotReadyException("not connected to any rdv: status ["+mJxtaNetworkManager.getPeerGroup().getRendezVousService().getRendezVousStatus()+"]");
384 throw new P2pProxyNotReadyException("initializing");
387 } catch (InterruptedException e) {
388 throw new P2pProxyNotReadyException(e);
391 /* p2pproxy.h implementation*/
392 private static int excecuteAction(Future<Integer> aResult, Class<? extends Callable<Integer>> classTaskName) {
394 if (aResult.isDone() == false) {
395 return P2pProxylauncherConstants.P2PPROXY_EWOULDBLOCK;
396 } else if (aResult == null) {
397 createAccountResult = Excecutor.pool.submit(classTaskName.newInstance());
399 Future<Integer> lResult = createAccountResult;
400 createAccountResult = null;
401 return lResult.get();
403 return P2pProxylauncherConstants.P2PPROXY_ERROR;
404 } catch (Exception e) {
405 return P2pProxylauncherConstants.P2PPROXY_ERROR;
409 static Future<Integer> createAccountResult = null;
410 public synchronized static int createAccount(final String aUserName) {
411 class CreateAcountTask implements Callable<Integer> {
412 public Integer call() throws Exception {
414 mP2pProxyAccountManagement.createAccount(aUserName);
415 } catch (P2pProxyUserAlreadyExistException e) {
416 return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_EXIST;
417 } catch (P2pProxyException e) {
418 return P2pProxylauncherConstants.P2PPROXY_ERROR;
420 return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
423 return excecuteAction(createAccountResult,CreateAcountTask.class);
426 static Future<Integer> deleteAccountResult = null;
427 public static int deleteAccount(final String aUserName) {
428 class DeleteAccountTask implements Callable<Integer> {
430 public Integer call() throws Exception {
431 mP2pProxyAccountManagement.deleteAccount(aUserName);
432 return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
436 return excecuteAction(deleteAccountResult,DeleteAccountTask.class);
439 static Future<Integer> isValidAccountResult = null;
440 public static int isValidAccount(final String aUserName){
441 class IsValidAccountResultTask implements Callable<Integer> {
443 public Integer call() throws Exception {
444 if (mP2pProxyAccountManagement.isValidAccount(aUserName)) {
445 return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_EXIST;
447 return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_NOT_EXIST;
452 return excecuteAction(isValidAccountResult,IsValidAccountResultTask.class);
455 static Future<Integer> lookupSipProxyUriResult = null;
456 public static String lookupSipProxyUri(final String aDomaine) {
459 String[] lProxies = mP2pProxySipProxyRegistrarManagement.lookupSipProxiesUri(aDomaine);
460 if (lProxies.length != 0) {
465 } catch (Exception e) {
470 public static String[] lookupSipProxiesUri(String aDomaine) {
473 return mP2pProxySipProxyRegistrarManagement.lookupSipProxiesUri(aDomaine);
474 } catch (Exception e) {
479 public static String[] lookupMediaServerAddress(String aDomaine) {
482 return mP2pProxySipProxyRegistrarManagement.getMediaServerList();
483 } catch (Exception e) {
484 mLog.error("cannot find media resource",e);
489 public static int getState() {
492 return P2pProxylauncherConstants.P2PPROXY_CONNECTED;
493 } catch (P2pProxyException e) {
494 //if (mLog != null) mLog.info("cannot get state",e);
495 return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
498 public static int revokeSipProxy(String aProxy) {
501 mP2pProxySipProxyRegistrarManagement.revokeSipProxy(aProxy);
502 return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
503 } catch (P2pProxyException e) {
504 return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
507 public static int revokeMediaServer(String aServer) {
510 mP2pProxySipProxyRegistrarManagement.revokeMediaServer(aServer);
511 return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
512 } catch (P2pProxyException e) {
513 return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
516 public static void stop() {