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 }