📄 snmp.java
字号:
if (pdu.size() == 0) {
logger.error("Illegal report PDU received from " + e.getPeerAddress() +
" missing report variable binding");
return;
}
VariableBinding vb = pdu.get(0);
if (vb == null) {
logger.error("Received illegal REPORT PDU from " + e.getPeerAddress());
return;
}
OID firstOID = vb.getOid();
boolean resend = false;
if (request.requestStatus < request.maxRequestStatus) {
switch (request.requestStatus) {
case 0:
if (SnmpConstants.usmStatsUnknownEngineIDs.equals(firstOID)) {
resend = true;
}
else if (SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) {
request.requestStatus++;
resend = true;
}
break;
case 1:
if (SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) {
resend = true;
}
break;
}
}
// if legal report PDU received, then resend request
if (resend) {
logger.debug("Send new request after report.");
request.requestStatus++;
try {
PduHandle resentHandle =
sendMessage(request.pdu, request.target, e.getTransportMapping());
// make sure reference to handle is hold until request is finished,
// because otherwise cache information may get lost (WeakHashMap)
request.key = resentHandle;
}
catch (IOException iox) {
logger.error("Failed to send message to " + request.target + ": " +
iox.getMessage());
return;
}
}
else {
boolean intime = request.cancel();
// remove pending request
// (sync is not needed as request is already canceled)
pendingRequests.remove(handle);
if (intime) {
// return report
request.listener.onResponse(new ResponseEvent(this,
e.getPeerAddress(),
request.pdu,
pdu,
request.userObject));
}
else {
// silently drop late report
if (logger.isInfoEnabled()) {
logger.info("Received late report from " +
e.getPeerAddress() +
" with request ID " + pdu.getRequestID());
}
}
}
}
/**
* Removes a <code>CommandResponderEvent</code> from this SNMP session.
* @param listener
* a previously added <code>CommandResponder</code> instance.
*/
public synchronized void removeCommandResponder(CommandResponder listener) {
if (commandResponderListeners != null &&
commandResponderListeners.contains(listener)) {
Vector v = (Vector) commandResponderListeners.clone();
v.removeElement(listener);
commandResponderListeners = v;
}
}
/**
* Adds a <code>CommandResponder</code> to this SNMP session.
* The command responder will then be informed about incoming SNMP PDUs of
* any kind that are not related to any outstanding requests of this SNMP
* session.
*
* @param listener CommandResponder
* the <code>CommandResponder</code> instance to be added.
*/
public synchronized void addCommandResponder(CommandResponder listener) {
Vector v = (commandResponderListeners == null) ?
new Vector(2) : (Vector) commandResponderListeners.clone();
if (!v.contains(listener)) {
v.addElement(listener);
commandResponderListeners = v;
}
}
/**
* Fires a <code>CommandResponderEvent</code> event to inform listeners about
* a received PDU. If a listener has marked the event as processed further
* listeners will not be informed about the event.
* @param event
* a <code>CommandResponderEvent</code>.
*/
protected void fireProcessPdu(CommandResponderEvent event) {
if (commandResponderListeners != null) {
Vector listeners = commandResponderListeners;
int count = listeners.size();
for (int i = 0; i < count; i++) {
((CommandResponder) listeners.elementAt(i)).processPdu(event);
// if event is marked as processed the event is not forwarded to
// remaining listeners
if (event.isProcessed()) {
return;
}
}
}
}
/**
* Gets the timeout model associated with this SNMP session.
* @return
* a TimeoutModel instance (never <code>null</code>).
* @see #setTimeoutModel(TimeoutModel timeoutModel)
*/
public TimeoutModel getTimeoutModel() {
return timeoutModel;
}
/**
* Sets the timeout model for this SNMP session. The default timeout model
* sends retries whenever the time specified by the <code>timeout</code>
* parameter of the target has elapsed without a response beeing received for
* the request. By specifying a different timeout model this behaviour can
* be changed.
* @param timeoutModel
* a <code>TimeoutModel</code> instance (must not be <code>null</code>).
*/
public void setTimeoutModel(TimeoutModel timeoutModel) {
if (timeoutModel == null) {
throw new NullPointerException("Timeout model cannot be null");
}
this.timeoutModel = timeoutModel;
}
class PendingRequest extends TimerTask {
private PduHandle key;
private int retryCount;
private ResponseListener listener;
private Object userObject;
private PDU pdu;
private Target target;
private TransportMapping transport;
private int requestStatus = 0;
// Maximum request status - allows to receive up to two reports and then
// send the original request again. A value of 0 is used for discovery.
private int maxRequestStatus = 2;
private volatile boolean finished = false;
public PendingRequest(PduHandle key,
ResponseListener listener,
Object userObject,
PDU pdu,
Target target,
TransportMapping transport) {
this.key = key;
this.userObject = userObject;
this.listener = listener;
this.retryCount = target.getRetries();
this.pdu = pdu;
this.target = target;
this.transport = transport;
}
private PendingRequest(PendingRequest other) {
this.key = other.key;
this.userObject = other.userObject;
this.listener = other.listener;
this.retryCount = other.retryCount - 1;
this.pdu = other.pdu;
this.target = other.target;
this.requestStatus = other.requestStatus;
}
/**
* run
*/
public synchronized void run() {
if ((!finished) && (retryCount > 0)) {
retryCount--;
try {
sendMessage(pdu, target, transport);
logger.debug("Running pending request with handle: " + key);
PendingRequest nextRetry = new PendingRequest(this);
synchronized (sync) {
pendingRequests.put(key, nextRetry);
long delay =
timeoutModel.getRetryTimeout(target.getRetries() - retryCount,
target.getRetries(),
target.getTimeout());
timer.schedule(nextRetry, delay);
}
}
catch (IOException ex) {
finished = true;
logger.error("Failed to send SNMP message to " + target.toString() +
": " +
ex.getMessage());
messageDispatcher.releaseStateReference(target.getVersion(), key);
listener.onResponse(new ResponseEvent(Snmp.this, null,
pdu, null, userObject,
ex));
}
}
else if (!finished) {
finished = true;
pendingRequests.remove(key);
// request timed out
if (logger.isDebugEnabled()) {
logger.debug("Request timed out: " + key.getTransactionID());
}
messageDispatcher.releaseStateReference(target.getVersion(), key);
listener.onResponse(new ResponseEvent(Snmp.this, null,
pdu, null, userObject));
}
}
public synchronized boolean setFinished() {
boolean currentState = finished;
this.finished = true;
return currentState;
}
public void setMaxRepuestStatus(int maxRepuestStatus) {
this.maxRequestStatus = maxRepuestStatus;
}
public int getMaxRepuestStatus() {
return maxRequestStatus;
}
}
class AsyncRequestKey {
private PDU request;
private ResponseListener listener;
public AsyncRequestKey(PDU request, ResponseListener listener) {
this.request = request;
this.listener = listener;
}
/**
* Indicates whether some other object is "equal to" this one.
*
* @param obj the reference object with which to compare.
* @return <code>true</code> if this object is the same as the obj argument;
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof AsyncRequestKey) {
AsyncRequestKey other = (AsyncRequestKey) obj;
return (request.equals(other.request) && listener.equals(other.listener));
}
return false;
}
public int hashCode() {
return request.hashCode();
}
}
class SyncResponseListener implements ResponseListener {
private ResponseEvent response = null;
/**
* onResponse
*
* @param event ResponseEvent
*/
public synchronized void onResponse(ResponseEvent event) {
this.response = event;
this.notify();
}
public ResponseEvent getResponse() {
return response;
}
}
class NotificationDispatcher implements CommandResponder {
// A mapping of transport addresses to transport mappings of notification
// listeners
private Hashtable notificationListeners = new Hashtable(10);
private Hashtable notificationTransports = new Hashtable(10);
public NotificationDispatcher() {
}
public synchronized void addNotificationListener(Address listenAddress,
TransportMapping transport,
CommandResponder listener){
notificationListeners.put(listenAddress, transport);
notificationTransports.put(transport, listener);
}
public synchronized boolean
removeNotificationListener(Address listenAddress)
{
TransportMapping tm =
(TransportMapping)notificationListeners.remove(listenAddress);
if (tm == null) {
return false;
}
tm.removeMessageDispatcher(messageDispatcher);
try {
tm.close();
}
catch (IOException ex) {
logger.error(ex);
if (logger.isDebugEnabled()) {
ex.printStackTrace();
}
}
return true;
}
public synchronized void closeAll() {
notificationTransports.clear();
for (Iterator it = notificationListeners.values().iterator();
it.hasNext();) {
TransportMapping tm = (TransportMapping) it.next();
try {
tm.close();
}
catch (IOException ex) {
logger.error(ex);
if (logger.isDebugEnabled()) {
ex.printStackTrace();
}
}
}
notificationListeners.clear();
}
public synchronized void processPdu(CommandResponderEvent event) {
CommandResponder listener = (CommandResponder)
notificationTransports.get(event.getTransportMapping());
if (listener != null) {
listener.processPdu(event);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -