1 package au.com.loftinspace.tcpreflector.io;
2
3 import au.com.loftinspace.tcpreflector.packet.Packet;
4 import au.com.loftinspace.tcpreflector.packet.PacketListener;
5
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.OutputStream;
9 import java.net.InetSocketAddress;
10 import java.util.Iterator;
11 import java.util.LinkedList;
12
13 /***
14 * Accepts input from the input stream and redirects it to the output stream
15 * @author Jem
16 */
17 public class PacketInterceptor implements Runnable {
18
19 private static final int MAX_PACKET_SIZE = 4096;
20
21 private LinkedList listeners;
22 private boolean active;
23 private byte[] buffer;
24 private InputStream inputStream;
25 private OutputStream outputStream;
26 private InterceptorManager interceptorManager;
27 private boolean reflective;
28 private InetSocketAddress toAddress;
29 private InetSocketAddress fromAddress;
30
31 public PacketInterceptor(InputStream inputStream, OutputStream outputStream, InterceptorManager interceptorManager, InetSocketAddress fromAddress, InetSocketAddress toAddress) {
32 this.outputStream = outputStream;
33 this.inputStream = inputStream;
34 this.interceptorManager = interceptorManager;
35 this.listeners = new LinkedList();
36 this.buffer = new byte[MAX_PACKET_SIZE];
37 this.active = true;
38 this.reflective = true;
39 this.toAddress = toAddress;
40 this.fromAddress = fromAddress;
41 }
42
43 public void addListener(PacketListener listener) {
44 listeners.add(listener);
45 }
46
47 public void removeListener(PacketListener listener) {
48 listeners.remove(listener);
49 }
50
51 public void removeAllListeners() {
52 listeners.clear();
53 }
54
55 public int getListenerCount() {
56 return listeners.size();
57 }
58
59 public void run() {
60 try {
61 while (active) {
62 redirectPacket();
63 }
64 } catch (IOException e) {
65 interceptorManager.terminateInterceptors();
66 }
67 }
68
69 public void terminate() {
70 active = false;
71 closeStream(inputStream);
72 closeStream(outputStream);
73 }
74
75 public boolean isActive() {
76 return active;
77 }
78
79 private void redirectPacket() throws IOException {
80 int bytesRead = inputStream.read(buffer, 0, MAX_PACKET_SIZE);
81 if (bytesRead == -1) {
82 interceptorManager.terminateInterceptors();
83 } else {
84 if (reflective) {
85 outputStream.write(buffer, 0, bytesRead);
86 outputStream.flush();
87 Packet packet = new Packet(buffer, bytesRead, fromAddress, toAddress);
88 adviseListeners(packet);
89 }
90 }
91 }
92
93 private void closeStream(InputStream inputStream) {
94 try {
95 if (inputStream != null) {
96 inputStream.close();
97 }
98 } catch (IOException ignored) {
99 }
100 }
101
102 private void closeStream(OutputStream outputStream) {
103 try {
104 if (outputStream != null) {
105 outputStream.close();
106 }
107 } catch (IOException ignored) {
108 }
109 }
110
111 private void adviseListeners(Packet packet) {
112 Iterator iter = listeners.iterator();
113 while (iter.hasNext()) {
114 PacketListener packetListener = (PacketListener) iter.next();
115 packetListener.add(packet);
116 }
117 }
118
119 public void setReflective(boolean reflective) {
120 this.reflective = reflective;
121 }
122 }