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    }