1 /*
2  * Created on 14-Jan-2005
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 org.gudy.azureus2.core3.util;
21 
22 import java.net.InetSocketAddress;
23 import java.net.URL;
24 import java.util.*;
25 
26 import org.gudy.azureus2.core3.config.COConfigurationManager;
27 import org.gudy.azureus2.core3.torrent.*;
28 
29 /**
30  * @author parg
31  *
32  */
33 
34 public class
35 AENetworkClassifier
36 {
37 		// DON'T change these constants as they get serialised!!!!
38 		// (obviously you can add new networks to them).
39 		// If you add to them remember to update the configuration item default for
40 		// "Network Selection Default.<name>" and
41 		// "Tracker Network Selection Default.<name>
42 
43 	public static final String	AT_PUBLIC		= "Public";
44 	public static final String	AT_I2P			= "I2P";
45 	public static final String	AT_TOR			= "Tor";
46 
47 	public static final String[]	AT_NETWORKS =
48 		{ AT_PUBLIC, AT_I2P, AT_TOR };
49 
50 	public static final String[] AT_NON_PUBLIC = { AT_I2P, AT_TOR };
51 
52 	private static List	listeners = new ArrayList();
53 
54 	public static String
categoriseAddress( String str )55 	categoriseAddress(
56 		String	str )
57 	{
58 		if ( str == null ){
59 
60 			return( AT_PUBLIC );	// woreva
61 		}
62 
63 		int len = str.length();
64 
65 		if ( len < 7 ){
66 
67 			return( AT_PUBLIC );
68 		}
69 
70 		char[] chars = str.toCharArray();
71 
72 		char last_char = chars[len-1];
73 
74 		if ( last_char >= '0' && last_char <= '9' ){
75 
76 			return( AT_PUBLIC );
77 
78 		}else if ( last_char == 'p' || last_char == 'P' ){
79 
80 			if ( 	chars[len-2] == '2' &&
81 					chars[len-4] == '.' ){
82 
83 				char c = chars[len-3];
84 
85 				if ( c == 'i' || c == 'I' ){
86 
87 					return( AT_I2P );
88 				}
89 			}
90 
91 			return( AT_PUBLIC );
92 
93 		}else if ( last_char == 'n' || last_char == 'N') {
94 
95 			if ( chars[len-6] == '.' ){
96 
97 				String temp = new String( chars, len-5, 4 ).toLowerCase( Locale.US );
98 
99 				if ( temp.equals( "onio" )){
100 
101 					return( AT_TOR );
102 				}
103 			}
104 		}
105 
106 		return( AT_PUBLIC );
107 	}
108 
109 	public static String
internalise( String str )110 	internalise(
111 		String	str )
112 	{
113 		if ( str == null ){
114 
115 			return( null );
116 
117 		}else{
118 
119 			for ( String net: AT_NETWORKS ){
120 
121 				if ( str.equalsIgnoreCase( net )){
122 
123 					return( net );
124 				}
125 			}
126 		}
127 
128 		return( null );
129 	}
130 
131 	public static String
categoriseAddress( InetSocketAddress isa )132 	categoriseAddress(
133 		InetSocketAddress		isa )
134 	{
135 		return( categoriseAddress( AddressUtils.getHostAddress( isa )));
136 	}
137 
138 	public static String[]
getNetworks( TOTorrent torrent, String display_name )139 	getNetworks(
140 		TOTorrent	torrent,
141 		String		display_name )
142 	{
143 			// go through all the announce URL and find all networks
144 
145 		List<URL>	urls = new ArrayList();
146 
147 		urls.add( torrent.getAnnounceURL());
148 
149 		TOTorrentAnnounceURLSet[] sets = torrent.getAnnounceURLGroup().getAnnounceURLSets();
150 
151 		for (int i=0;i<sets.length;i++){
152 
153 			URL[]	u = sets[i].getAnnounceURLs();
154 
155 			for (int j=0;j<u.length;j++){
156 
157 				urls.add( u[j] );
158 			}
159 		}
160 
161 		List<String>	available_networks = new ArrayList<String>();
162 
163 		for (int i=0;i<urls.size();i++){
164 
165 			URL	u = (URL)urls.get(i);
166 
167 			String	network = categoriseAddress( u.getHost());
168 
169 			if ( !available_networks.contains( network )){
170 
171 				available_networks.add( network );
172 			}
173 		}
174 
175 		if ( available_networks.size() == 1 && available_networks.get(0) == AT_PUBLIC ){
176 
177 			return( new String[]{ AT_PUBLIC });
178 		}
179 
180 
181 		boolean	prompt = COConfigurationManager.getBooleanParameter( "Network Selection Prompt" );
182 
183 		List<String>	res = new ArrayList<String>();
184 
185 		if ( prompt && listeners.size() > 0 ){
186 
187 			String[]	t_nets = new String[available_networks.size()];
188 
189 			available_networks.toArray( t_nets );
190 
191 			for (int i=0;i<listeners.size();i++){
192 
193 				try{
194 					String[]	selected = ((AENetworkClassifierListener)listeners.get(i)).selectNetworks(
195 											display_name,
196 											t_nets );
197 
198 					if ( selected != null ){
199 
200 						for (int j=0;j<selected.length;j++){
201 
202 							res.add( selected[j] );
203 						}
204 					}
205 				}catch( Throwable e ){
206 
207 					Debug.printStackTrace(e);
208 				}
209 			}
210 
211 		}else{
212 				// use enabled defaults to proceed
213 
214 
215 			for (int i=0;i<available_networks.size();i++){
216 
217 				if ( COConfigurationManager.getBooleanParameter( "Network Selection Default." + available_networks.get(i))){
218 
219 					res.add( available_networks.get(i));
220 				}
221 			}
222 		}
223 
224 		String[]	x = new String[res.size()];
225 
226 		res.toArray( x );
227 
228 		return( x );
229 	}
230 
231 	public static String[]
getDefaultNetworks()232 	getDefaultNetworks()
233 	{
234 		List<String>	res = new ArrayList<String>();
235 
236 		for ( String net: AT_NETWORKS ){
237 
238 			if ( COConfigurationManager.getBooleanParameter( "Network Selection Default." + net )){
239 
240 				res.add( net );
241 			}
242 		}
243 
244 		String[]	x = new String[res.size()];
245 
246 		res.toArray( x );
247 
248 		return( x );
249 	}
250 
251 	public static void
addListener( AENetworkClassifierListener l )252 	addListener(
253 		AENetworkClassifierListener	l )
254 	{
255 		listeners.add(l);
256 	}
257 
258 	public static void
removeListener( AENetworkClassifierListener l )259 	removeListener(
260 		AENetworkClassifierListener	l )
261 	{
262 		listeners.remove(l);
263 	}
264 
265 	public static void
main( String[] args )266 	main(
267 		String[]		args )
268 	{
269 		String[] tests = {
270 			null,
271 			"12345",
272 			"192.168.1.2",
273 			"fred.i2p",
274 			"fred.i2",
275 			"bill.onion",
276 			"bill.onio"
277 		};
278 
279 		for ( String str: tests ){
280 
281 			System.out.println( str + " -> " + categoriseAddress( str ));
282 		}
283 	}
284 }
285