001 /**************************************************************** 002 * This work is derived from 'jnamed.java' distributed in * 003 * 'dnsjava-2.0.5'. This original is licensed as follows: * 004 * Copyright (c) 1999-2005, Brian Wellington * 005 * All rights reserved. * 006 * * 007 * Redistribution and use in source and binary forms, with or * 008 * without modification, are permitted provided that the * 009 * following conditions are met: * 010 * * 011 * * Redistributions of source code must retain the above * 012 * copyright notice, this list of conditions and the * 013 * following disclaimer. * 014 * * Redistributions in binary form must reproduce the above * 015 * copyright notice, this list of conditions and the * 016 * following disclaimer in the documentation and/or other * 017 * materials provided with the distribution. * 018 * * Neither the name of the dnsjava project nor the names * 019 * of its contributors may be used to endorse or promote * 020 * products derived from this software without specific * 021 * prior written permission. * 022 * * 023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * 024 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * 025 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * 026 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * 027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * 028 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * 029 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * 030 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * 031 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * 032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 033 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 034 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * 035 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 036 * POSSIBILITY OF SUCH DAMAGE. * 037 * * 038 * Modifications are * 039 * Licensed to the Apache Software Foundation (ASF) under one * 040 * or more contributor license agreements. See the NOTICE file * 041 * distributed with this work for additional information * 042 * regarding copyright ownership. The ASF licenses this file * 043 * to you under the Apache License, Version 2.0 (the * 044 * "License"); you may not use this file except in compliance * 045 * with the License. You may obtain a copy of the License at * 046 * * 047 * http://www.apache.org/licenses/LICENSE-2.0 * 048 * * 049 * Unless required by applicable law or agreed to in writing, * 050 * software distributed under the License is distributed on an * 051 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 052 * KIND, either express or implied. See the License for the * 053 * specific language governing permissions and limitations * 054 * under the License. * 055 ****************************************************************/ 056 057 package org.apache.james.jspf.tester; 058 059 import java.io.IOException; 060 import java.io.InterruptedIOException; 061 import java.net.DatagramPacket; 062 import java.net.DatagramSocket; 063 import java.net.InetAddress; 064 065 public final class UDPListener implements Runnable { 066 067 private final static class UDPResponder implements Runnable { 068 private ResponseGenerator responseGenerator; 069 070 private DatagramSocket sock; 071 private InetAddress addr; 072 private int port; 073 private byte[] in; 074 075 private UDPResponder(DatagramSocket sock, InetAddress addr, int port, byte[] in, ResponseGenerator rg) { 076 this.sock = sock; 077 this.addr = addr; 078 this.port = port; 079 this.in = in; 080 this.responseGenerator = rg; 081 } 082 083 public void run() { 084 try { 085 DatagramPacket outdp = null; 086 byte[] response = responseGenerator.generateReply(in, in.length); 087 if (response == null) 088 return; 089 if (outdp == null) { 090 outdp = new DatagramPacket(response, response.length, 091 addr, port); 092 } else { 093 outdp.setData(response); 094 outdp.setLength(response.length); 095 outdp.setAddress(addr); 096 outdp.setPort(port); 097 } 098 sock.send(outdp); 099 } 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 }