1 package au.com.loftinspace.tcpreflector;
2
3 import au.com.loftinspace.tcpreflector.io.InterceptorManager;
4 import au.com.loftinspace.tcpreflector.io.PacketInterceptor;
5 import au.com.loftinspace.tcpreflector.packet.PacketListener;
6
7 import java.io.IOException;
8 import java.net.InetSocketAddress;
9 import java.net.Socket;
10
11 /***
12 * Reflects TCP packets delivered to and received from a network socket address.
13 * @author Jem Mawson
14 */
15 public class Reflector implements InterceptorManager {
16
17 private Socket clientSocket;
18 private Socket destinationSocket;
19 private PacketInterceptor clientToDestinationHandler;
20 private PacketInterceptor destinationToClientHandler;
21
22 public Reflector(Socket clientSocket, Socket destinationSocket) throws IOException {
23 this.clientSocket = clientSocket;
24 this.destinationSocket = destinationSocket;
25 InetSocketAddress clientAddress = new InetSocketAddress(clientSocket.getInetAddress(), clientSocket.getPort());
26 InetSocketAddress destinationAddress = new InetSocketAddress(destinationSocket.getInetAddress(), destinationSocket.getPort());
27 clientToDestinationHandler = new PacketInterceptor(clientSocket.getInputStream(), destinationSocket.getOutputStream(), this, clientAddress, destinationAddress);
28 destinationToClientHandler = new PacketInterceptor(destinationSocket.getInputStream(), clientSocket.getOutputStream(), this, destinationAddress, clientAddress);
29 }
30
31 public void startReflecting() {
32 String clientToDestinationThreadName = "PacketInterceptor " +
33 clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " -> " +
34 destinationSocket.getInetAddress() + ":" + destinationSocket.getPort();
35
36 String destinationToClientThreadName = "PacketInterceptor " +
37 clientSocket.getInetAddress() + ":" + clientSocket.getPort() + " <- " +
38 destinationSocket.getInetAddress() + ":" + destinationSocket.getPort();
39
40 new Thread(clientToDestinationHandler, clientToDestinationThreadName).start();
41 new Thread(destinationToClientHandler, destinationToClientThreadName).start();
42 }
43
44 public void waitForCompletion() {
45 while (packetReceiversActive()) {
46 try {
47 Thread.sleep(250);
48 } catch(InterruptedException ignored) {
49 }
50 }
51 terminateInterceptors();
52 }
53
54 public void terminateInterceptors() {
55 if (destinationToClientHandler.isActive()) {
56 destinationToClientHandler.terminate();
57 }
58 if (clientToDestinationHandler.isActive()) {
59 clientToDestinationHandler.terminate();
60 }
61 terminateSocket(clientSocket);
62 terminateSocket(destinationSocket);
63 }
64
65 private void terminateSocket(Socket socket) {
66 try {
67 if (socket != null) {
68 socket.close();
69 }
70 } catch (IOException ignored) {
71 }
72 }
73
74 private boolean packetReceiversActive() {
75 return (clientToDestinationHandler.isActive()) && (destinationToClientHandler.isActive());
76 }
77
78 public void addListener(PacketListener listener) {
79 clientToDestinationHandler.addListener(listener);
80 destinationToClientHandler.addListener(listener);
81 }
82
83 public void removeListener(PacketListener listener) {
84 clientToDestinationHandler.removeListener(listener);
85 destinationToClientHandler.removeListener(listener);
86 }
87
88 public void setReflective(boolean reflective) {
89 clientToDestinationHandler.setReflective(reflective);
90 destinationToClientHandler.setReflective(reflective);
91 }
92
93 public void setResponseReflective(boolean reflective) {
94 destinationToClientHandler.setReflective(reflective);
95 }
96
97 public void removeAllListeners() {
98 clientToDestinationHandler.removeAllListeners();
99 destinationToClientHandler.removeAllListeners();
100 }
101 }