1 /*
2  * Created on 22 Jun 2006
3  * Created by Paul Gardner
4  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
5  *
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.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  */
19 
20 package com.aelitis.azureus.core.networkmanager.impl.udp;
21 
22 import org.gudy.azureus2.core3.config.COConfigurationManager;
23 import org.gudy.azureus2.core3.config.ParameterListener;
24 import org.gudy.azureus2.core3.logging.LogAlert;
25 import org.gudy.azureus2.core3.logging.Logger;
26 import org.gudy.azureus2.core3.util.Constants;
27 import org.gudy.azureus2.core3.util.Debug;
28 import org.gudy.azureus2.core3.util.RandomUtils;
29 
30 import com.aelitis.azureus.core.networkmanager.impl.ProtocolDecoderPHE;
31 import com.aelitis.net.udp.uc.PRUDPPacket;
32 
33 public class
34 UDPNetworkManager
35 {
36 	public static final boolean	MINIMISE_OVERHEADS	= true;
37 
38 	public static final int MIN_INCOMING_INITIAL_PACKET_SIZE = ProtocolDecoderPHE.MIN_INCOMING_INITIAL_PACKET_SIZE;
39 	public static final int MAX_INCOMING_INITIAL_PACKET_SIZE = ProtocolDecoderPHE.getMaxIncomingInitialPacketSize(MINIMISE_OVERHEADS);
40 
41 	private static final int MIN_MSS = 128;
42 	private static final int MAX_MSS = PRUDPPacket.MAX_PACKET_SIZE;
43 
44 	private static int udp_mss_size;
45 
46 	public static boolean UDP_INCOMING_ENABLED;
47 	public static boolean UDP_OUTGOING_ENABLED;
48 
49 	static{
50 		COConfigurationManager.addAndFireParameterListener(
51 				"UDP.Listen.Port.Enable",
52 				new ParameterListener()
53 				{
54 					public void
55 					parameterChanged(
56 						String name )
57 					{
58 						UDP_INCOMING_ENABLED = UDP_OUTGOING_ENABLED = COConfigurationManager.getBooleanParameter( name );
59 					}
60 				});
61 	}
62 
getUdpMssSize()63 	public static int getUdpMssSize() {  return udp_mss_size;  }
64 
65 	public static void
refreshRates( int min_rate )66 	refreshRates(
67 		int		min_rate )
68 	{
69 		udp_mss_size = COConfigurationManager.getIntParameter( "network.udp.mtu.size" ) - 40;
70 
71 	    if( udp_mss_size > min_rate )  udp_mss_size = min_rate - 1;
72 
73 	    if( udp_mss_size < MIN_MSS )  udp_mss_size = MIN_MSS;
74 
75 	    if ( udp_mss_size > MAX_MSS ) udp_mss_size = MAX_MSS;
76 	}
77 
78 	private static UDPNetworkManager	singleton;
79 
80 
81 	public static UDPNetworkManager
getSingleton()82 	getSingleton()
83 	{
84 		synchronized( UDPNetworkManager.class ){
85 
86 			if ( singleton == null ){
87 
88 				singleton = new UDPNetworkManager();
89 			}
90 		}
91 
92 		return( singleton );
93 	}
94 
95 	private int udp_listen_port	= -1;
96 	private int udp_non_data_listen_port = -1;
97 
98 	private UDPConnectionManager	_connection_manager;
99 
100 	protected
UDPNetworkManager()101 	UDPNetworkManager()
102 	{
103 		COConfigurationManager.addAndFireParameterListener(
104 			   "UDP.Listen.Port",
105 			   new ParameterListener()
106 			   {
107 				   public void
108 				   parameterChanged(String name)
109 				   {
110 					   int port = COConfigurationManager.getIntParameter( name );
111 
112 					   if ( port == udp_listen_port ){
113 
114 						   return;
115 					   }
116 
117 					   if ( port < 0 || port > 65535 || port == Constants.INSTANCE_PORT ) {
118 
119 					        String msg = "Invalid incoming UDP listen port configured, " +port+ ". The port has been reset. Please check your config!";
120 
121 					        Debug.out( msg );
122 
123 					        Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg));
124 
125 					        udp_listen_port = RandomUtils.generateRandomNetworkListenPort();
126 
127 					        COConfigurationManager.setParameter( name, udp_listen_port );
128 
129 					    }else{
130 
131 					    	udp_listen_port	= port;
132 					    }
133 				   }
134 			   });
135 
136 		COConfigurationManager.addAndFireParameterListener(
137 				   "UDP.NonData.Listen.Port",
138 				   new ParameterListener()
139 				   {
140 					   public void
141 					   parameterChanged(String name)
142 					   {
143 						   int port = COConfigurationManager.getIntParameter( name );
144 
145 						   if ( port == udp_non_data_listen_port ){
146 
147 							   return;
148 						   }
149 
150 						   if ( port < 0 || port > 65535 || port == Constants.INSTANCE_PORT ) {
151 
152 						        String msg = "Invalid incoming UDP non-data listen port configured, " +port+ ". The port has been reset. Please check your config!";
153 
154 						        Debug.out( msg );
155 
156 						        Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, msg));
157 
158 						        udp_non_data_listen_port = RandomUtils.generateRandomNetworkListenPort();
159 
160 						        COConfigurationManager.setParameter( name, udp_non_data_listen_port );
161 
162 						    }else{
163 
164 						    	udp_non_data_listen_port	= port;
165 						    }
166 					   }
167 				   });
168 	}
169 
170 	public boolean
isUDPListenerEnabled()171 	isUDPListenerEnabled()
172 	{
173 		return( UDP_INCOMING_ENABLED );
174 	}
175 
176 	public int
getUDPListeningPortNumber()177 	getUDPListeningPortNumber()
178 	{
179 		return( udp_listen_port );
180 	}
181 
182 	public boolean
isUDPNonDataListenerEnabled()183 	isUDPNonDataListenerEnabled()
184 	{
185 		return( UDP_INCOMING_ENABLED );
186 	}
187 
188 	public int
getUDPNonDataListeningPortNumber()189 	getUDPNonDataListeningPortNumber()
190 	{
191 		return( udp_non_data_listen_port );
192 	}
193 
194 	public UDPConnectionManager
getConnectionManager()195 	getConnectionManager()
196 	{
197 		synchronized( this ){
198 
199 			if ( _connection_manager == null ){
200 
201 				_connection_manager = new UDPConnectionManager();
202 			}
203 		}
204 
205 		return( _connection_manager );
206 	}
207 }
208