1   /*
2    * $Id: FirewallTestCase.java 7963 2007-08-21 08:53:15Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.test.firewall;
12  
13  import org.mule.config.factories.HostNameFactory;
14  
15  import java.io.IOException;
16  import java.net.DatagramSocket;
17  import java.net.InetAddress;
18  import java.net.ServerSocket;
19  import java.net.Socket;
20  import java.net.DatagramPacket;
21  import java.net.UnknownHostException;
22  import java.security.SecureRandom;
23  
24  import junit.framework.TestCase;
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  public class FirewallTestCase extends TestCase
29  {
30  
31      public static final String LOCALHOST = "localhost";
32      public static final String LOCALADDR = "127.0.0.1";
33      public static final int TEST_COUNT = 1;
34  
35      protected final Log logger = LogFactory.getLog(this.getClass());
36  
37      private SecureRandom random = new SecureRandom();
38  
39      public void testLoopback() throws Exception
40      {
41          // this gives localhost.localdomain on sourceforge
42  //        consistentAddress(LOCALHOST, true);
43          consistentAddress(LOCALHOST, false);
44  //        assertEquals("Strange name for loopback", LOCALHOST, InetAddress.getByName(LOCALADDR).getCanonicalHostName());
45      }
46  
47      public void testLocalHost() throws Exception
48      {
49          InetAddress aLocalAddress = InetAddress.getLocalHost();
50          logger.info("Java returns " + addressToString(aLocalAddress) + " as the 'local' address");
51          assertNotSame("No external address", LOCALADDR, aLocalAddress.getHostAddress());
52          consistentAddress(aLocalAddress.getHostName(), false);
53          assertEquals("Inconsistent hostname", aLocalAddress.getHostName(), new HostNameFactory().create(null));
54      }
55  
56      public void testCanonicalHost() throws Exception
57      {
58          InetAddress aLocalAddress = InetAddress.getLocalHost();
59          assertNotSame("No extrernal name", LOCALHOST, aLocalAddress.getCanonicalHostName());
60          consistentAddress(aLocalAddress.getCanonicalHostName(), true);
61      }
62  
63      protected void consistentAddress(String name, boolean canonical) throws UnknownHostException
64      {
65          String address = InetAddress.getByName(name).getHostAddress();
66          logger.debug("Testing relationship between " + name + " and " + address);
67          assertEquals("Name " + name + " is inconsistent", name,
68                  name(InetAddress.getByName(name), canonical));
69          assertEquals("Address " + address + " is inconsistent", address,
70                  InetAddress.getByName(address).getHostAddress());
71          // we cannot expect to go from address to name consistently, but we can expect
72          // names always to resolve to the same address, and for addresses not to change
73          // when going via a name (in other words, any aliases are consistent).
74          assertEquals(name + " -> " + address + " is inconsistent", address,
75                  InetAddress.getByName(name).getHostAddress());
76          assertEquals(name + " -> " + address + " -> " + name + " -> " + address + " is inconsistent", address,
77                  InetAddress.getByName(
78                          name(
79                                  InetAddress.getByName(
80                                          InetAddress.getByName(name).getHostAddress()), canonical)).getHostAddress());
81      }
82  
83      protected String name(InetAddress address, boolean canonical)
84      {
85          if (canonical)
86          {
87              return address.getCanonicalHostName();
88          }
89          else
90          {
91              return address.getHostName();
92          }
93      }
94  
95      public void testLocalhostTcp() throws Exception
96      {
97          for (int i = 0; i < TEST_COUNT; ++i)
98          {
99              doTestTcp(InetAddress.getByName(LOCALHOST), randomPrivatePort());
100         }
101     }
102 
103     public void testHostnameTcp() throws Exception
104     {
105         for (int i = 0; i < TEST_COUNT; ++i)
106         {
107             doTestTcp(InetAddress.getLocalHost(), randomPrivatePort());
108         }
109     }
110 
111     public void testLocalhostUdp() throws Exception
112     {
113         for (int i = 0; i < TEST_COUNT; ++i)
114         {
115             doTestUdp(InetAddress.getByName(LOCALHOST), randomPrivatePort());
116         }
117     }
118 
119     public void testHostnameUdp() throws Exception
120     {
121         for (int i = 0; i < TEST_COUNT; ++i)
122         {
123             doTestUdp(InetAddress.getLocalHost(), randomPrivatePort());
124         }
125     }
126 
127     protected void doTestTcp(InetAddress address, int port) throws Exception
128     {
129         try
130         {
131             logger.debug("Testing TCP on " + addressToString(address, port));
132             ServerSocket server = openTcpServer(address, port);
133             Socket client = openTcpClient(address, port);
134             Socket receiver = server.accept();
135             client.getOutputStream().write(1);
136             assertEquals("Failed to send byte via " + addressToString(address, port),
137                     1, receiver.getInputStream().read());
138             client.close();
139             server.close();
140         }
141         catch (Exception e)
142         {
143             logger.error("Error while attempting TCP message on " + addressToString(address, port));
144             throw e;
145         }
146     }
147 
148     protected void doTestUdp(InetAddress address, int port) throws Exception
149     {
150         try
151         {
152             logger.debug("Testing UDP on " + addressToString(address, port));
153             DatagramSocket server = openUdpServer(address, port);
154             DatagramSocket client = openUdpClient();
155             client.send(new DatagramPacket(new byte[]{1}, 1, address, port));
156             DatagramPacket packet = new DatagramPacket(new byte[1], 1);
157             server.receive(packet);
158             assertEquals("Failed to send packet via " + addressToString(address, port),
159                     1, packet.getData()[0]);
160             client.close();
161             server.close();
162         }
163         catch (Exception e)
164         {
165             logger.error("Error while attempting UDP message on " + addressToString(address, port));
166             throw e;
167         }
168     }
169 
170     protected Socket openTcpClient(InetAddress address, int port) throws IOException
171     {
172         try
173         {
174             return new Socket(address, port);
175         }
176         catch (IOException e)
177         {
178             logger.error("Could not open TCP client to " + addressToString(address, port));
179             throw e;
180         }
181     }
182 
183     protected ServerSocket openTcpServer(InetAddress address, int port) throws IOException
184     {
185         try
186         {
187             return new ServerSocket(port, 1, address);
188         }
189         catch (IOException e)
190         {
191             logger.error("Could not open TCP server on " + addressToString(address, port));
192             throw e;
193         }
194     }
195 
196     protected DatagramSocket openUdpServer(InetAddress address, int port) throws IOException
197     {
198         try
199         {
200             return new DatagramSocket(port, address);
201         }
202         catch (IOException e)
203         {
204             logger.error("Could not open UDP server on " + addressToString(address, port));
205             throw e;
206         }
207     }
208 
209     protected DatagramSocket openUdpClient() throws IOException
210     {
211         try
212         {
213             return new DatagramSocket();
214         }
215         catch (IOException e)
216         {
217             logger.error("Could not open UDP client");
218             throw e;
219         }
220     }
221 
222     protected String addressToString(InetAddress address, int port)
223     {
224         return addressToString(address) + ":" + port;
225     }
226 
227     protected String addressToString(InetAddress address)
228     {
229         return address.getHostName() + "/" + address.getCanonicalHostName() + "/" + address.getHostAddress();
230     }
231 
232     protected int randomPrivatePort()
233     {
234         return randomPort(49152, 65535);
235     }
236 
237     /**
238      * @param lo
239      * @param hi
240      * @return A number between lo and hi (inclusive)
241      */
242     protected int randomPort(int lo, int hi)
243     {
244         return lo + random.nextInt(hi - lo + 1);
245     }
246 
247 }