1 /****************************************************************
2 * This work is derived from 'jnamed.java' distributed in *
3 * 'dnsjava-2.0.5'. This original is licensed as follows: *
4 * Copyright (c) 1999-2005, Brian Wellington *
5 * All rights reserved. *
6 * *
7 * Redistribution and use in source and binary forms, with or *
8 * without modification, are permitted provided that the *
9 * following conditions are met: *
10 * *
11 * * Redistributions of source code must retain the above *
12 * copyright notice, this list of conditions and the *
13 * following disclaimer. *
14 * * Redistributions in binary form must reproduce the above *
15 * copyright notice, this list of conditions and the *
16 * following disclaimer in the documentation and/or other *
17 * materials provided with the distribution. *
18 * * Neither the name of the dnsjava project nor the names *
19 * of its contributors may be used to endorse or promote *
20 * products derived from this software without specific *
21 * prior written permission. *
22 * *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR *
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *
35 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
36 * POSSIBILITY OF SUCH DAMAGE. *
37 * *
38 * Modifications are *
39 * Licensed to the Apache Software Foundation (ASF) under one *
40 * or more contributor license agreements. See the NOTICE file *
41 * distributed with this work for additional information *
42 * regarding copyright ownership. The ASF licenses this file *
43 * to you under the Apache License, Version 2.0 (the *
44 * "License"); you may not use this file except in compliance *
45 * with the License. You may obtain a copy of the License at *
46 * *
47 * http://www.apache.org/licenses/LICENSE-2.0 *
48 * *
49 * Unless required by applicable law or agreed to in writing, *
50 * software distributed under the License is distributed on an *
51 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
52 * KIND, either express or implied. See the License for the *
53 * specific language governing permissions and limitations *
54 * under the License. *
55 ****************************************************************/
56
57 package org.apache.james.jspf.tester;
58
59 import java.io.IOException;
60 import java.io.InterruptedIOException;
61 import java.net.DatagramPacket;
62 import java.net.DatagramSocket;
63 import java.net.InetAddress;
64
65 public final class UDPListener implements Runnable {
66
67 private final static class UDPResponder implements Runnable {
68 private ResponseGenerator responseGenerator;
69
70 private DatagramSocket sock;
71 private InetAddress addr;
72 private int port;
73 private byte[] in;
74
75 private UDPResponder(DatagramSocket sock, InetAddress addr, int port, byte[] in, ResponseGenerator rg) {
76 this.sock = sock;
77 this.addr = addr;
78 this.port = port;
79 this.in = in;
80 this.responseGenerator = rg;
81 }
82
83 public void run() {
84 try {
85 DatagramPacket outdp = null;
86 byte[] response = responseGenerator.generateReply(in, in.length);
87 if (response == null)
88 return;
89 if (outdp == null) {
90 outdp = new DatagramPacket(response, response.length,
91 addr, port);
92 } else {
93 outdp.setData(response);
94 outdp.setLength(response.length);
95 outdp.setAddress(addr);
96 outdp.setPort(port);
97 }
98 sock.send(outdp);
99 } catch (IOException e) {
100 System.out.println("UDPResponder(" + addr.getHostAddress() + "#" + port + "): "
101 + e);
102 }
103 }
104
105 }
106
107
108
109 private final InetAddress addr;
110
111 private final int port;
112
113 private ResponseGenerator responseGenerator;
114
115 UDPListener(InetAddress addr, int port, ResponseGenerator rg) {
116 this.addr = addr;
117 this.port = port;
118 this.responseGenerator = rg;
119 }
120
121 public void run() {
122 try {
123 DatagramSocket sock = new DatagramSocket(port, addr);
124 final short udpLength = 512;
125 byte[] in = new byte[udpLength];
126 DatagramPacket indp = new DatagramPacket(in, in.length);
127 while (true) {
128 indp.setLength(in.length);
129 try {
130 sock.receive(indp);
131 } catch (InterruptedIOException e) {
132 continue;
133 }
134
135 byte[] local = new byte[indp.getLength()];
136 System.arraycopy(in, 0, local, 0, indp.getLength());
137 Runnable runnable = new UDPResponder(sock, indp.getAddress(), indp.getPort(), local, responseGenerator);
138
139 new Thread(runnable).start();
140 }
141 } catch (IOException e) {
142 System.out.println("UDPListener(" + addr.getHostAddress() + "#" + port + "): "
143 + e);
144 }
145 }
146
147 }