jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp/daemon/SnmpRequestHandler.java
changeset 27222 422e90d83a4e
parent 27221 a34b97a133ea
parent 27220 315d620f5726
child 27235 b666d0408ad6
--- a/jdk/src/jdk.snmp/share/classes/com/sun/jmx/snmp/daemon/SnmpRequestHandler.java	Thu Oct 23 11:19:17 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1149 +0,0 @@
-/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package com.sun.jmx.snmp.daemon;
-
-
-
-// java import
-//
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.logging.Level;
-import java.io.InterruptedIOException;
-import java.net.DatagramSocket;
-import java.net.DatagramPacket;
-import java.net.SocketException;
-
-// jmx imports
-//
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import com.sun.jmx.snmp.SnmpMessage;
-import com.sun.jmx.snmp.SnmpPduFactory;
-import com.sun.jmx.snmp.SnmpPduBulk;
-import com.sun.jmx.snmp.SnmpPduPacket;
-import com.sun.jmx.snmp.SnmpPduRequest;
-import com.sun.jmx.snmp.SnmpPduTrap;
-import com.sun.jmx.snmp.SnmpValue;
-import com.sun.jmx.snmp.SnmpVarBind;
-import com.sun.jmx.snmp.SnmpVarBindList;
-import com.sun.jmx.snmp.SnmpDefinitions;
-import com.sun.jmx.snmp.SnmpStatusException;
-import com.sun.jmx.snmp.SnmpTooBigException;
-import com.sun.jmx.snmp.SnmpDataTypeEnums;
-
-// RI imports
-//
-import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
-
-// SNMP runtime import
-//
-import com.sun.jmx.snmp.agent.SnmpMibAgent;
-import com.sun.jmx.snmp.agent.SnmpUserDataFactory;
-//import com.sun.jmx.snmp.IPAcl.IPAcl;
-import com.sun.jmx.snmp.InetAddressAcl;
-
-
-class SnmpRequestHandler extends ClientHandler implements SnmpDefinitions {
-
-    private transient DatagramSocket       socket = null ;
-    private transient DatagramPacket       packet = null ;
-    private transient Vector<SnmpMibAgent> mibs = null ;
-
-    /**
-     * Contains the list of sub-requests associated to the current request.
-     */
-    private transient Hashtable<SnmpMibAgent, SnmpSubRequestHandler> subs = null;
-
-    /**
-     * Reference on the MIBS
-     */
-    private transient SnmpMibTree root;
-
-    private transient InetAddressAcl      ipacl = null ;
-    private transient SnmpPduFactory      pduFactory = null ;
-    private transient SnmpUserDataFactory userDataFactory = null ;
-    private transient SnmpAdaptorServer adaptor = null;
-    /**
-     * Full constructor
-     */
-    public SnmpRequestHandler(SnmpAdaptorServer server, int id,
-                              DatagramSocket s, DatagramPacket p,
-                              SnmpMibTree tree, Vector<SnmpMibAgent> m,
-                              InetAddressAcl a,
-                              SnmpPduFactory factory,
-                              SnmpUserDataFactory dataFactory,
-                              MBeanServer f, ObjectName n)
-    {
-        super(server, id, f, n);
-
-        // Need a reference on SnmpAdaptorServer for getNext & getBulk,
-        // in case of oid equality (mib overlapping).
-        //
-        adaptor = server;
-        socket = s;
-        packet = p;
-        root= tree;
-        mibs = new Vector<>(m);
-        subs= new Hashtable<>(mibs.size());
-        ipacl = a;
-        pduFactory = factory ;
-        userDataFactory = dataFactory ;
-        //thread.start();
-    }
-
-    /**
-     * Treat the request available in 'packet' and send the result
-     * back to the client.
-     * Note: we overwrite 'packet' with the response bytes.
-     */
-    @Override
-    public void doRun() {
-
-        // Trace the input packet
-        //
-        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                    "doRun","Packet received:\n" +
-                    SnmpMessage.dumpHexBuffer(packet.getData(), 0, packet.getLength()));
-        }
-
-        // Let's build the response packet
-        //
-        DatagramPacket respPacket = makeResponsePacket(packet) ;
-
-        // Trace the output packet
-        //
-        if ((SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) && (respPacket != null)) {
-            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                    "doRun","Packet to be sent:\n" +
-                    SnmpMessage.dumpHexBuffer(respPacket.getData(), 0, respPacket.getLength()));
-        }
-
-        // Send the response packet if any
-        //
-        if (respPacket != null) {
-            try {
-                socket.send(respPacket) ;
-            } catch (SocketException e) {
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    if (e.getMessage().equals(InterruptSysCallMsg)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                            "doRun", "interrupted");
-                    } else {
-                      SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                            "doRun", "I/O exception", e);
-                    }
-                }
-            } catch(InterruptedIOException e) {
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                        "doRun", "interrupted");
-                }
-            } catch(Exception e) {
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                        "doRun", "failure when sending response", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Here we make a response packet from a request packet.
-     * We return null if there no response packet to sent.
-     */
-    private DatagramPacket makeResponsePacket(DatagramPacket reqPacket) {
-        DatagramPacket respPacket = null ;
-
-        // Transform the request packet into a request SnmpMessage
-        //
-        SnmpMessage reqMsg = new SnmpMessage() ;
-        try {
-            reqMsg.decodeMessage(reqPacket.getData(), reqPacket.getLength()) ;
-            reqMsg.address = reqPacket.getAddress() ;
-            reqMsg.port = reqPacket.getPort() ;
-        }
-        catch(SnmpStatusException x) {
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                    "makeResponsePacket", "packet decoding failed", x);
-            }
-            reqMsg = null ;
-            ((SnmpAdaptorServer)adaptorServer).incSnmpInASNParseErrs(1) ;
-        }
-
-        // Make the response SnmpMessage if any
-        //
-        SnmpMessage respMsg = null ;
-        if (reqMsg != null) {
-            respMsg = makeResponseMessage(reqMsg) ;
-        }
-
-        // Try to transform the response SnmpMessage into response packet.
-        // NOTE: we overwrite the request packet.
-        //
-        if (respMsg != null) {
-            try {
-                reqPacket.setLength(respMsg.encodeMessage(reqPacket.getData())) ;
-                respPacket = reqPacket ;
-            }
-            catch(SnmpTooBigException x) {
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                        "makeResponsePacket", "response message is too big");
-                }
-                try {
-                    respMsg = newTooBigMessage(reqMsg) ;
-                    reqPacket.setLength(respMsg.encodeMessage(reqPacket.getData())) ;
-                    respPacket = reqPacket ;
-                }
-                catch(SnmpTooBigException xx) {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                            "makeResponsePacket", "'too big' is 'too big' !!!");
-                    }
-                    adaptor.incSnmpSilentDrops(1);
-                }
-            }
-        }
-
-        return respPacket ;
-    }
-
-    /**
-     * Here we make a response message from a request message.
-     * We return null if there is no message to reply.
-     */
-    private SnmpMessage makeResponseMessage(SnmpMessage reqMsg) {
-        SnmpMessage respMsg = null ;
-
-        // Transform the request message into a request pdu
-        //
-        SnmpPduPacket reqPdu;
-        Object userData = null;
-        try {
-            reqPdu = (SnmpPduPacket)pduFactory.decodeSnmpPdu(reqMsg) ;
-            if (reqPdu != null && userDataFactory != null)
-                userData = userDataFactory.allocateUserData(reqPdu);
-        }
-        catch(SnmpStatusException x) {
-            reqPdu = null ;
-            SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;
-            snmpServer.incSnmpInASNParseErrs(1) ;
-            if (x.getStatus()== SnmpDefinitions.snmpWrongSnmpVersion)
-                snmpServer.incSnmpInBadVersions(1) ;
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                    "makeResponseMessage", "message decoding failed", x);
-            }
-        }
-
-        // Make the response pdu if any
-        //
-        SnmpPduPacket respPdu = null ;
-        if (reqPdu != null) {
-            respPdu = makeResponsePdu(reqPdu,userData) ;
-            try {
-                if (userDataFactory != null)
-                    userDataFactory.releaseUserData(userData,respPdu);
-            } catch (SnmpStatusException x) {
-                respPdu = null;
-            }
-        }
-
-        // Try to transform the response pdu into a response message if any
-        //
-        if (respPdu != null) {
-            try {
-                respMsg = (SnmpMessage)pduFactory.
-                    encodeSnmpPdu(respPdu, packet.getData().length) ;
-            }
-            catch(SnmpStatusException x) {
-                respMsg = null ;
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                        "makeResponseMessage", "failure when encoding the response message", x);
-                }
-            }
-            catch(SnmpTooBigException x) {
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                        "makeResponseMessage", "response message is too big");
-                }
-
-                try {
-                    // if the PDU is too small, why should we try to do
-                    // recovery ?
-                    //
-                    if (packet.getData().length <=32)
-                        throw x;
-                    int pos= x.getVarBindCount();
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                            "makeResponseMessage", "fail on element" + pos);
-                    }
-                    int old;
-                    while (true) {
-                        try {
-                            respPdu = reduceResponsePdu(reqPdu, respPdu, pos) ;
-                            respMsg = (SnmpMessage)pduFactory.
-                                encodeSnmpPdu(respPdu,
-                                              packet.getData().length -32) ;
-                            break;
-                        } catch (SnmpTooBigException xx) {
-                            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                                    "makeResponseMessage", "response message is still too big");
-                            }
-                            old= pos;
-                            pos= xx.getVarBindCount();
-                            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                                    "makeResponseMessage","fail on element" + pos);
-                            }
-                            if (pos == old) {
-                                // we can not go any further in trying to
-                                // reduce the message !
-                                //
-                                throw xx;
-                            }
-                        }
-                    }// end of loop
-                } catch(SnmpStatusException xx) {
-                    respMsg = null ;
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                           "makeResponseMessage", "failure when encoding the response message", xx);
-                    }
-                }
-                catch(SnmpTooBigException xx) {
-                    try {
-                        respPdu = newTooBigPdu(reqPdu) ;
-                        respMsg = (SnmpMessage)pduFactory.
-                            encodeSnmpPdu(respPdu, packet.getData().length) ;
-                    }
-                    catch(SnmpTooBigException xxx) {
-                        respMsg = null ;
-                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                               "makeResponseMessage", "'too big' is 'too big' !!!");
-                        }
-                        adaptor.incSnmpSilentDrops(1);
-                    }
-                    catch(Exception xxx) {
-                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                               "makeResponseMessage", "Got unexpected exception", xxx);
-                        }
-                        respMsg = null ;
-                    }
-                }
-                catch(Exception xx) {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                           "makeResponseMessage", "Got unexpected exception", xx);
-                    }
-                    respMsg = null ;
-                }
-            }
-        }
-        return respMsg ;
-    }
-
-    /**
-     * Here we make a response pdu from a request pdu.
-     * We return null if there is no pdu to reply.
-     */
-    private SnmpPduPacket makeResponsePdu(SnmpPduPacket reqPdu,
-                                          Object userData) {
-
-        SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;
-        SnmpPduPacket respPdu = null ;
-
-        snmpServer.updateRequestCounters(reqPdu.type) ;
-        if (reqPdu.varBindList != null)
-            snmpServer.updateVarCounters(reqPdu.type,
-                                         reqPdu.varBindList.length) ;
-
-        if (checkPduType(reqPdu)) {
-            respPdu = checkAcl(reqPdu) ;
-            if (respPdu == null) { // reqPdu is accepted by ACLs
-                if (mibs.size() < 1) {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                           "makeResponsePdu", "Request " + reqPdu.requestId +
-                           " received but no MIB registered.");
-                    }
-                    return makeNoMibErrorPdu((SnmpPduRequest)reqPdu, userData);
-                }
-                switch(reqPdu.type) {
-                case SnmpPduPacket.pduGetRequestPdu:
-                case SnmpPduPacket.pduGetNextRequestPdu:
-                case SnmpPduPacket.pduSetRequestPdu:
-                    respPdu = makeGetSetResponsePdu((SnmpPduRequest)reqPdu,
-                                                    userData) ;
-                    break ;
-
-                case SnmpPduPacket.pduGetBulkRequestPdu:
-                    respPdu = makeGetBulkResponsePdu((SnmpPduBulk)reqPdu,
-                                                     userData) ;
-                    break ;
-                }
-            }
-            else { // reqPdu is rejected by ACLs
-                // respPdu contains the error response to be sent.
-                // We send this response only if authResEnabled is true.
-                if (!snmpServer.getAuthRespEnabled()) { // No response should be sent
-                    respPdu = null ;
-                }
-                if (snmpServer.getAuthTrapEnabled()) { // A trap must be sent
-                    try {
-                        snmpServer.snmpV1Trap(SnmpPduTrap.
-                                              trapAuthenticationFailure, 0,
-                                              new SnmpVarBindList()) ;
-                    }
-                    catch(Exception x) {
-                        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                            SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                               "makeResponsePdu", "Failure when sending authentication trap", x);
-                        }
-                    }
-                }
-            }
-        }
-        return respPdu ;
-    }
-
-    //
-    // Generates a response packet, filling the values in the
-    // varbindlist with one of endOfMibView, noSuchObject, noSuchInstance
-    // according to the value of <code>status</code>
-    //
-    // @param statusTag should be one of:
-    //        <li>SnmpDataTypeEnums.errEndOfMibViewTag</li>
-    //        <li>SnmpDataTypeEnums.errNoSuchObjectTag</li>
-    //        <li>SnmpDataTypeEnums.errNoSuchInstanceTag</li>
-    //
-    SnmpPduPacket makeErrorVarbindPdu(SnmpPduPacket req, int statusTag) {
-
-        final SnmpVarBind[] vblist = req.varBindList;
-        final int length = vblist.length;
-
-        switch (statusTag) {
-        case SnmpDataTypeEnums.errEndOfMibViewTag:
-            for (int i=0 ; i<length ; i++)
-                vblist[i].value = SnmpVarBind.endOfMibView;
-            break;
-        case SnmpDataTypeEnums.errNoSuchObjectTag:
-            for (int i=0 ; i<length ; i++)
-                vblist[i].value = SnmpVarBind.noSuchObject;
-            break;
-        case SnmpDataTypeEnums.errNoSuchInstanceTag:
-            for (int i=0 ; i<length ; i++)
-                vblist[i].value = SnmpVarBind.noSuchInstance;
-            break;
-        default:
-            return newErrorResponsePdu(req,snmpRspGenErr,1);
-        }
-        return newValidResponsePdu(req,vblist);
-    }
-
-    // Generates an appropriate response when no mib is registered in
-    // the adaptor.
-    //
-    // <li>If the version is V1:</li>
-    // <ul><li>Generates a NoSuchName error V1 response PDU</li></ul>
-    // <li>If the version is V2:</li>
-    // <ul><li>If the request is a GET, fills the varbind list with
-    //         NoSuchObject's</li>
-    //     <li>If the request is a GET-NEXT/GET-BULK, fills the varbind
-    //         list with EndOfMibView's</li>
-    //     <li>If the request is a SET, generates a NoAccess error V2
-    //          response PDU</li>
-    // </ul>
-    //
-    //
-    SnmpPduPacket makeNoMibErrorPdu(SnmpPduRequest req, Object userData) {
-        // There is no agent registered
-        //
-        if (req.version == SnmpDefinitions.snmpVersionOne) {
-            // Version 1: => NoSuchName
-            return
-                newErrorResponsePdu(req,snmpRspNoSuchName,1);
-        } else if (req.version == SnmpDefinitions.snmpVersionTwo) {
-            // Version 2: => depends on PDU type
-            switch (req.type) {
-            case pduSetRequestPdu :
-            case pduWalkRequest :
-                // SET request => NoAccess
-                return
-                    newErrorResponsePdu(req,snmpRspNoAccess,1);
-            case pduGetRequestPdu :
-                // GET request => NoSuchObject
-                return
-                    makeErrorVarbindPdu(req,SnmpDataTypeEnums.
-                                        errNoSuchObjectTag);
-            case pduGetNextRequestPdu :
-            case pduGetBulkRequestPdu :
-                // GET-NEXT or GET-BULK => EndOfMibView
-                return
-                    makeErrorVarbindPdu(req,SnmpDataTypeEnums.
-                                        errEndOfMibViewTag);
-            default:
-            }
-        }
-        // Something wrong here: => snmpRspGenErr
-        return newErrorResponsePdu(req,snmpRspGenErr,1);
-    }
-
-    /**
-     * Here we make the response pdu from a get/set request pdu.
-     * At this level, the result is never null.
-     */
-    private SnmpPduPacket makeGetSetResponsePdu(SnmpPduRequest req,
-                                                Object userData) {
-
-        // Create the trhead group specific for handling sub-requests
-        // associated to the current request. Use the invoke id
-        //
-        // Nice idea to use a thread group on a request basis.
-        // However the impact on performance is terrible !
-        // theGroup= new ThreadGroup(thread.getThreadGroup(),
-        //                "request " + String.valueOf(req.requestId));
-
-        // Let's build the varBindList for the response pdu
-        //
-
-        if (req.varBindList == null) {
-            // Good ! Let's make a full response pdu.
-            //
-            return newValidResponsePdu(req, null) ;
-        }
-
-        // First we need to split the request into subrequests
-        //
-        splitRequest(req);
-        int nbSubRequest= subs.size();
-        if (nbSubRequest == 1)
-            return turboProcessingGetSet(req,userData);
-
-
-        // Execute all the subrequests resulting from the split of the
-        // varbind list.
-        //
-        SnmpPduPacket result= executeSubRequest(req,userData);
-        if (result != null)
-            // It means that an error occurred. The error is already
-            // formatted by the executeSubRequest
-            // method.
-            return result;
-
-        // So far so good. So we need to concatenate all the answers.
-        //
-        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-               "makeGetSetResponsePdu",
-               "Build the unified response for request " + req.requestId);
-        }
-        return mergeResponses(req);
-    }
-
-    /**
-     * The method runs all the sub-requests associated to the current
-     * instance of SnmpRequestHandler.
-     */
-    private SnmpPduPacket executeSubRequest(SnmpPduPacket req,
-                                            Object userData) {
-
-        int errorStatus = SnmpDefinitions.snmpRspNoError ;
-
-        int i;
-        // If it's a set request, we must first check any varBind
-        //
-        if (req.type == pduSetRequestPdu) {
-
-            i=0;
-            for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements() ; i++) {
-                // Indicate to the sub request that a check must be invoked ...
-                // OK we should have defined out own tag for that !
-                //
-                SnmpSubRequestHandler sub= e.nextElement();
-                sub.setUserData(userData);
-                sub.type= pduWalkRequest;
-
-                sub.run();
-
-                sub.type= pduSetRequestPdu;
-
-                if (sub.getErrorStatus() != SnmpDefinitions.snmpRspNoError) {
-                    // No point to go any further.
-                    //
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                           "executeSubRequest", "an error occurs");
-                    }
-
-                    return newErrorResponsePdu(req, errorStatus,
-                                               sub.getErrorIndex() + 1) ;
-                }
-            }
-        }// end processing check operation for a set PDU.
-
-        // Let's start the sub-requests.
-        //
-        i=0;
-        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements() ;i++) {
-            SnmpSubRequestHandler sub= e.nextElement();
-        /* NPCTE fix for bugId 4492741, esc 0, 16-August 2001 */
-            sub.setUserData(userData);
-        /* end of NPCTE fix for bugId 4492741 */
-
-            sub.run();
-
-            if (sub.getErrorStatus() != SnmpDefinitions.snmpRspNoError) {
-                // No point to go any further.
-                //
-                if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                    SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                       "executeSubRequest", "an error occurs");
-                }
-
-                return newErrorResponsePdu(req, errorStatus,
-                                           sub.getErrorIndex() + 1) ;
-            }
-        }
-
-        // everything is ok
-        //
-        return null;
-    }
-
-    /**
-     * Optimize when there is only one sub request
-     */
-    private SnmpPduPacket turboProcessingGetSet(SnmpPduRequest req,
-                                                Object userData) {
-
-        int errorStatus;
-        SnmpSubRequestHandler sub = subs.elements().nextElement();
-        sub.setUserData(userData);
-
-        // Indicate to the sub request that a check must be invoked ...
-        // OK we should have defined out own tag for that !
-        //
-        if (req.type == SnmpDefinitions.pduSetRequestPdu) {
-            sub.type= pduWalkRequest;
-            sub.run();
-            sub.type= pduSetRequestPdu;
-
-            // Check the error status.
-            //
-            errorStatus= sub.getErrorStatus();
-            if (errorStatus != SnmpDefinitions.snmpRspNoError) {
-                // No point to go any further.
-                //
-                return newErrorResponsePdu(req, errorStatus,
-                                           sub.getErrorIndex() + 1) ;
-            }
-        }
-
-        // process the operation
-        //
-
-        sub.run();
-        errorStatus= sub.getErrorStatus();
-        if (errorStatus != SnmpDefinitions.snmpRspNoError) {
-            // No point to go any further.
-            //
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "turboProcessingGetSet", "an error occurs");
-            }
-            int realIndex= sub.getErrorIndex() + 1;
-            return newErrorResponsePdu(req, errorStatus, realIndex) ;
-        }
-
-        // So far so good. So we need to concatenate all the answers.
-        //
-
-        if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-            SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-               "turboProcessingGetSet",  "build the unified response for request "
-                + req.requestId);
-        }
-        return mergeResponses(req);
-    }
-
-    /**
-     * Here we make the response pdu for a bulk request.
-     * At this level, the result is never null.
-     */
-    private SnmpPduPacket makeGetBulkResponsePdu(SnmpPduBulk req,
-                                                 Object userData) {
-
-        SnmpVarBind[] respVarBindList;
-
-        // RFC 1905, Section 4.2.3, p14
-        int L = req.varBindList.length ;
-        int N = Math.max(Math.min(req.nonRepeaters, L), 0) ;
-        int M = Math.max(req.maxRepetitions, 0) ;
-        int R = L - N ;
-
-        if (req.varBindList == null) {
-            // Good ! Let's make a full response pdu.
-            //
-            return newValidResponsePdu(req, null) ;
-        }
-
-        // Split the request into subrequests.
-        //
-        splitBulkRequest(req, N, M, R);
-        SnmpPduPacket result= executeSubRequest(req,userData);
-        if (result != null)
-            return result;
-
-        respVarBindList= mergeBulkResponses(N + (M * R));
-
-        // Now we remove useless trailing endOfMibView.
-        //
-        int m2 ; // respVarBindList[m2] item and next are going to be removed
-        int t = respVarBindList.length ;
-        while ((t > N) && (respVarBindList[t-1].
-                           value.equals(SnmpVarBind.endOfMibView))) {
-            t-- ;
-        }
-        if (t == N)
-            m2 = N + R ;
-        else
-            m2 = N + ((t -1 -N) / R + 2) * R ; // Trivial, of course...
-        if (m2 < respVarBindList.length) {
-            SnmpVarBind[] truncatedList = new SnmpVarBind[m2] ;
-            for (int i = 0 ; i < m2 ; i++) {
-                truncatedList[i] = respVarBindList[i] ;
-            }
-            respVarBindList = truncatedList ;
-        }
-
-        // Good ! Let's make a full response pdu.
-        //
-        return newValidResponsePdu(req, respVarBindList) ;
-    }
-
-    /**
-     * Check the type of the pdu: only the get/set/bulk request
-     * are accepted.
-     */
-    private boolean checkPduType(SnmpPduPacket pdu) {
-
-        boolean result;
-
-        switch(pdu.type) {
-
-        case SnmpDefinitions.pduGetRequestPdu:
-        case SnmpDefinitions.pduGetNextRequestPdu:
-        case SnmpDefinitions.pduSetRequestPdu:
-        case SnmpDefinitions.pduGetBulkRequestPdu:
-            result = true ;
-            break;
-
-        default:
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "checkPduType", "cannot respond to this kind of PDU");
-            }
-            result = false ;
-            break;
-        }
-
-        return result ;
-    }
-
-    /**
-     * Check if the specified pdu is conform to the ACL.
-     * This method returns null if the pdu is ok. If not, it returns
-     * the response pdu to be replied.
-     */
-    private SnmpPduPacket checkAcl(SnmpPduPacket pdu) {
-        SnmpPduPacket response = null ;
-        String community = new String(pdu.community) ;
-
-        // We check the pdu type and create an error response if
-        // the check failed.
-        //
-        if (ipacl != null) {
-            if (pdu.type == SnmpDefinitions.pduSetRequestPdu) {
-                if (!ipacl.checkWritePermission(pdu.address, community)) {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                           "checkAcl", "sender is " + pdu.address +
-                              " with " + community +". Sender has no write permission");
-                    }
-                    int err = SnmpSubRequestHandler.
-                        mapErrorStatus(SnmpDefinitions.
-                                       snmpRspAuthorizationError,
-                                       pdu.version, pdu.type);
-                    response = newErrorResponsePdu(pdu, err, 0) ;
-                }
-                else {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                           "checkAcl", "sender is " + pdu.address +
-                              " with " + community +". Sender has write permission");
-                    }
-                }
-            }
-            else {
-                if (!ipacl.checkReadPermission(pdu.address, community)) {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                           "checkAcl", "sender is " + pdu.address +
-                              " with " + community +". Sender has no read permission");
-                    }
-                    int err = SnmpSubRequestHandler.
-                        mapErrorStatus(SnmpDefinitions.
-                                       snmpRspAuthorizationError,
-                                       pdu.version, pdu.type);
-                    response = newErrorResponsePdu(pdu,
-                                                   err,
-                                                   0);
-                    SnmpAdaptorServer snmpServer =
-                        (SnmpAdaptorServer)adaptorServer;
-                    snmpServer.updateErrorCounters(SnmpDefinitions.
-                                                   snmpRspNoSuchName);
-                }
-                else {
-                    if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                        SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                           "checkAcl", "sender is " + pdu.address +
-                              " with " + community +". Sender has read permission");
-                    }
-                }
-            }
-        }
-
-        // If the response is not null, this means the pdu is rejected.
-        // So let's update the statistics.
-        //
-        if (response != null) {
-            SnmpAdaptorServer snmpServer = (SnmpAdaptorServer)adaptorServer ;
-            snmpServer.incSnmpInBadCommunityUses(1) ;
-            if (ipacl.checkCommunity(community) == false)
-                snmpServer.incSnmpInBadCommunityNames(1) ;
-        }
-
-        return response ;
-    }
-
-    /**
-     * Make a response pdu with the specified error status and index.
-     * NOTE: the response pdu share its varBindList with the request pdu.
-     */
-    private SnmpPduRequest newValidResponsePdu(SnmpPduPacket reqPdu,
-                                               SnmpVarBind[] varBindList) {
-        SnmpPduRequest result = new SnmpPduRequest() ;
-
-        result.address = reqPdu.address ;
-        result.port = reqPdu.port ;
-        result.version = reqPdu.version ;
-        result.community = reqPdu.community ;
-        result.type = SnmpPduRequest.pduGetResponsePdu ;
-        result.requestId = reqPdu.requestId ;
-        result.errorStatus = SnmpDefinitions.snmpRspNoError ;
-        result.errorIndex = 0 ;
-        result.varBindList = varBindList ;
-
-        ((SnmpAdaptorServer)adaptorServer).
-            updateErrorCounters(result.errorStatus) ;
-
-        return result ;
-    }
-
-    /**
-     * Make a response pdu with the specified error status and index.
-     * NOTE: the response pdu share its varBindList with the request pdu.
-     */
-    private SnmpPduRequest newErrorResponsePdu(SnmpPduPacket req,int s,int i) {
-        SnmpPduRequest result = newValidResponsePdu(req, null) ;
-        result.errorStatus = s ;
-        result.errorIndex = i ;
-        result.varBindList = req.varBindList ;
-
-        ((SnmpAdaptorServer)adaptorServer).
-            updateErrorCounters(result.errorStatus) ;
-
-        return result ;
-    }
-
-    private SnmpMessage newTooBigMessage(SnmpMessage reqMsg)
-        throws SnmpTooBigException {
-        SnmpMessage result = null ;
-        SnmpPduPacket reqPdu;
-
-        try {
-            reqPdu = (SnmpPduPacket)pduFactory.decodeSnmpPdu(reqMsg) ;
-            if (reqPdu != null) {
-                SnmpPduPacket respPdu = newTooBigPdu(reqPdu) ;
-                result = (SnmpMessage)pduFactory.
-                    encodeSnmpPdu(respPdu, packet.getData().length) ;
-            }
-        }
-        catch(SnmpStatusException x) {
-            // This should not occur because decodeIncomingRequest has normally
-            // been successfully called before.
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "newTooBigMessage", "Internal error", x);
-            }
-            throw new InternalError(x) ;
-        }
-
-        return result ;
-    }
-
-    private SnmpPduPacket newTooBigPdu(SnmpPduPacket req) {
-        SnmpPduRequest result =
-            newErrorResponsePdu(req, SnmpDefinitions.snmpRspTooBig, 0) ;
-        result.varBindList = null ;
-        return result ;
-    }
-
-    private SnmpPduPacket reduceResponsePdu(SnmpPduPacket req,
-                                            SnmpPduPacket resp,
-                                            int acceptedVbCount)
-        throws SnmpTooBigException {
-
-        // Reduction can be attempted only on bulk response
-        //
-        if (req.type != SnmpPduPacket.pduGetBulkRequestPdu) {
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "reduceResponsePdu", "cannot remove anything");
-            }
-            throw new SnmpTooBigException(acceptedVbCount) ;
-        }
-
-        // We're going to reduce the varbind list.
-        // First determine which items should be removed.
-        // Next duplicate and replace the existing list by the reduced one.
-        //
-        // acceptedVbCount is the number of varbind which have been
-        // successfully encoded before reaching bufferSize:
-        //   * when it is >= 2, we split the varbindlist at this
-        //     position (-1 to be safe),
-        //   * when it is 1, we only put one (big?) item in the varbindlist
-        //   * when it is 0 (in fact, acceptedVbCount is not available),
-        //     we split the varbindlist by 2.
-        //
-        int vbCount;
-        if (acceptedVbCount >= 3)
-            vbCount = Math.min(acceptedVbCount - 1, resp.varBindList.length) ;
-        else if (acceptedVbCount == 1)
-            vbCount = 1 ;
-        else // acceptedCount == 0 ie it is unknown
-            vbCount = resp.varBindList.length / 2 ;
-
-        if (vbCount < 1) {
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "reduceResponsePdu", "cannot remove anything");
-            }
-            throw new SnmpTooBigException(acceptedVbCount) ;
-        }
-        else {
-            SnmpVarBind[] newVbList = new SnmpVarBind[vbCount] ;
-            for (int i = 0 ; i < vbCount ; i++) {
-                newVbList[i] = resp.varBindList[i] ;
-            }
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, dbgTag,
-                   "reduceResponsePdu", (resp.varBindList.length - newVbList.length) +
-                    " items have been removed");
-            }
-            resp.varBindList = newVbList ;
-        }
-
-        return resp ;
-    }
-
-    /**
-     * The method takes the incoming requests and split it into subrequests.
-     */
-    private void splitRequest(SnmpPduRequest req) {
-
-        int nbAgents= mibs.size();
-        SnmpMibAgent agent = mibs.firstElement();
-        if (nbAgents == 1) {
-            // Take all the oids contained in the request and
-            //
-            subs.put(agent, new SnmpSubRequestHandler(agent, req, true));
-            return;
-        }
-
-        // For the get next operation we are going to send the varbind list
-        // to all agents
-        //
-        if (req.type == pduGetNextRequestPdu) {
-            for(Enumeration<SnmpMibAgent> e= mibs.elements(); e.hasMoreElements(); ) {
-                final SnmpMibAgent ag= e.nextElement();
-                subs.put(ag, new SnmpSubNextRequestHandler(adaptor, ag, req));
-            }
-            return;
-        }
-
-        int nbReqs= req.varBindList.length;
-        SnmpVarBind[] vars= req.varBindList;
-        SnmpSubRequestHandler sub;
-        for(int i=0; i < nbReqs; i++) {
-            agent= root.getAgentMib(vars[i].oid);
-            sub= subs.get(agent);
-            if (sub == null) {
-                // We need to create the sub request handler and update
-                // the hashtable
-                //
-                sub= new SnmpSubRequestHandler(agent, req);
-                subs.put(agent, sub);
-            }
-
-            // Update the translation table within the subrequest
-            //
-            sub.updateRequest(vars[i], i);
-        }
-    }
-
-    /**
-     * The method takes the incoming get bulk requests and split it into
-     * subrequests.
-     */
-    private void splitBulkRequest(SnmpPduBulk req,
-                                  int nonRepeaters,
-                                  int maxRepetitions,
-                                  int R) {
-        // Send the getBulk to all agents
-        //
-        for(Enumeration<SnmpMibAgent> e= mibs.elements(); e.hasMoreElements(); ) {
-            final SnmpMibAgent agent = e.nextElement();
-
-            if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
-                SNMP_ADAPTOR_LOGGER.logp(Level.FINER, dbgTag,
-                   "splitBulkRequest", "Create a sub with : " + agent + " " + nonRepeaters
-                   + " " + maxRepetitions + " " + R);
-            }
-
-            subs.put(agent,
-                     new SnmpSubBulkRequestHandler(adaptor,
-                                                   agent,
-                                                   req,
-                                                   nonRepeaters,
-                                                   maxRepetitions,
-                                                   R));
-        }
-    }
-
-    private SnmpPduPacket mergeResponses(SnmpPduRequest req) {
-
-        if (req.type == pduGetNextRequestPdu) {
-            return mergeNextResponses(req);
-        }
-
-        SnmpVarBind[] result= req.varBindList;
-
-        // Go through the list of subrequests and concatenate.
-        // Hopefully, by now all the sub-requests should be finished
-        //
-        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) {
-            SnmpSubRequestHandler sub= e.nextElement();
-            sub.updateResult(result);
-        }
-        return newValidResponsePdu(req,result);
-    }
-
-    private SnmpPduPacket mergeNextResponses(SnmpPduRequest req) {
-        int max= req.varBindList.length;
-        SnmpVarBind[] result= new SnmpVarBind[max];
-
-        // Go through the list of subrequests and concatenate.
-        // Hopefully, by now all the sub-requests should be finished
-        //
-        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) {
-            SnmpSubRequestHandler sub= e.nextElement();
-            sub.updateResult(result);
-        }
-
-        if (req.version == snmpVersionTwo) {
-            return newValidResponsePdu(req,result);
-        }
-
-        // In v1 make sure there is no endOfMibView ...
-        //
-        for(int i=0; i < max; i++) {
-            SnmpValue val= result[i].value;
-            if (val == SnmpVarBind.endOfMibView)
-                return newErrorResponsePdu(req,
-                                   SnmpDefinitions.snmpRspNoSuchName, i+1);
-        }
-
-        // So far so good ...
-        //
-        return newValidResponsePdu(req,result);
-    }
-
-    private SnmpVarBind[] mergeBulkResponses(int size) {
-        // Let's allocate the array for storing the result
-        //
-        SnmpVarBind[] result= new SnmpVarBind[size];
-        for(int i= size-1; i >=0; --i) {
-            result[i]= new SnmpVarBind();
-            result[i].value= SnmpVarBind.endOfMibView;
-        }
-
-        // Go through the list of subrequests and concatenate.
-        // Hopefully, by now all the sub-requests should be finished
-        //
-        for(Enumeration<SnmpSubRequestHandler> e= subs.elements(); e.hasMoreElements();) {
-            SnmpSubRequestHandler sub= e.nextElement();
-            sub.updateResult(result);
-        }
-
-        return result;
-    }
-
-    @Override
-    protected String makeDebugTag() {
-        return "SnmpRequestHandler[" + adaptorServer.getProtocol() + ":" +
-            adaptorServer.getPort() + "]";
-    }
-
-    @Override
-    Thread createThread(Runnable r) {
-        return null;
-    }
-
-    static final private String InterruptSysCallMsg =
-        "Interrupted system call";
-}