README.thread
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:13k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. Improved Error Reporting and Thread-Safe Use of the SNMP Library
  2. There is a need in some environments to support multiple threads
  3. in a single application.  The SNMP Library provides the Single Session
  4. functions which support thread-safe operation when certain precautions
  5. are taken.  This document describes the operation of the SNMP Library
  6. with a focus on its session management functions.  The Traditional API
  7. and the Single API functions are compared and contrasted.
  8. A working understanding of the CMU or UCD SNMP Library
  9. API is recommended to fully appreciate the concepts discussed.
  10. The document ends with a list of restrictions for using the Single API
  11. in a multi-threaded application.
  12. Unfortunately, the SNMPv3 support was added about the same time as
  13. the thread support and since they occurred in parallel the SNMPv3
  14. support was never checked for multi-threading correctness.  It is
  15. most likely that it is not thread-safe at this time.
  16.   ***** IMPORTANT ANNOUNCEMENT *****
  17.   To the point, no resource locks are applied within the SNMP Library.
  18.   The APDU encoding and some session management functions can be used
  19.   in thread-safe manners. The MIB file parsing is not thread-safe.
  20.   The Single Session API was made available in November 1998.
  21.   Existing applications use the Traditional API, which is not thread-safe.
  22.   The thread-safe considerations are discussed throughout this document.
  23. The research and development of the Single Session API that I've completed
  24. was wholly funded by my employer, Internet Security Systems, Inc.
  25. and is distributed freely to the Internet community.
  26. -Mike Slifcak, 23 April 1999
  27. 09 July 1999 Removed references to snmp_synch_setup and snmp_synch_reset
  28. Availability
  29. The Single Session API is integrated into the currently available
  30. versions of the CMU SNMP library and the UC-Davis SNMP package.
  31.  ftp://ftp.net.cmu.edu/pub/snmp/cmu-snmp-V1.13.tar.gz and later
  32.   Read : snmp_sess_api.3, Changes.SingleSession
  33.  ftp://ucd-snmp.ucdavis.edu/ucd-snmp-3.6.tar.gz and later
  34.   Read : snmp_sess_api.3, README.thread (after version 3.6.1)
  35. Both libraries work equally well in Windows NT and various
  36. UNIX platforms.  Please read this document and refer to
  37. the snmp_sess_api section 3 manual page.
  38. Glossary of Terms
  39. APDU    Application Protocol Data Unit
  40. API     Application Programming Interface
  41. CMU     Carnegie-Mellon University, Pittsburgh, PA.
  42. Library The SNMP library; Both CMU and UCD versions are applicable.
  43. Session Concept embodying the management of transacting SNMP APDUS.
  44. SNMP    Simple Network Management Protocol
  45. UCD     University of California at Davis, CA.
  46. Introduction
  47. The Library extends the UNIX file concept (open, close, read, write) to a Session.
  48. Opening a Session binds a local socket to a well-known port and creates internal
  49. structures to help with controlling the transaction of SNMP APDUs.  Closing a
  50. Session releases the memory and system resources used for these purposes.
  51. Since the mid-1980s, many SNMP applications have used the Traditional Session
  52. API to transact SNMP APDUs between the local host and SNMP-enabled devices.
  53.   The Traditional Session API does not support multi-threaded applications:
  54.   1)  There are no resource locks to prevent exposing the Library's
  55.       global data resources to corruption in a multi-threaded application;
  56.   2)  The Traditional API functions that receive SNMP APDUs
  57.       do not provide an interface for one of many sessions;
  58.   3)  Errors discovered by the Library are communicated through global
  59.       data structures and are not associated with the session
  60.       in which the error occurred.
  61.   The Single Session API provides these capabilities:
  62.   1)  Manage a single SNMP session safely, in multi-threaded or
  63.       non-threaded applications, by avoiding access to data structures
  64.       that the Traditional Session API may share between Sessions;
  65.   2)  Associate errors with the session context for threaded
  66.       and non-threaded applications.
  67. Contrasting and Comparing Traditional API and Single API
  68. The Traditional API uses the struct snmp_session pointer returned
  69. from snmp_open() to identify one SNMP session.  The Single API uses
  70. the opaque pointer returned from snmp_sess_open() to identify one
  71. SNMP session.
  72.    Helpful Hint : The Library copies the contents of the
  73.    structure which is input to snmp_open() and snmp_sess_open().
  74.    Once copied, changing that input structure's data
  75.    has no effect on the opened SNMP Session.
  76. The Traditional API uses the snmp_error() function to identify any
  77. library and system errors that occurred during the processing for
  78. one SNMP session.   The Single API uses snmp_sess_error() for the
  79. same purpose.
  80. The Traditional API manages the private Sessions list structure;
  81. adding to the list during snmp_open(), removing during snmp_close.
  82. With few exceptions, the Traditional API calls the Single API
  83. for each session that appears on the Sessions list.
  84. The Traditional API reads from all Sessions on the Sessions list;
  85. The Single API does not use the Sessions list.
  86. The Single API can read from only one Session.
  87.    Helpful Hint :
  88.    This is the basis for thread-safe-ness of the Library.
  89.    There are no resource locks applied.
  90. Using the Single API
  91. A multi-threaded application that deploys the SNMP Library should
  92. should complete all MIB file parsing before additional threads
  93. are activated.  Drawing from the parsed contents of the MIB does
  94. not incur any data corruption exposure once the internal MIB structures
  95. are initialised.
  96. The application may create threads such that a single thread may manage
  97. a single SNMP session.  The thread should call snmp_sess_init()
  98. to prepare a struct snmp_session structure.  The thread can adjust
  99. session parameters such as the remote UDP port or the local UDP port,
  100. which must be set prior to invoking snmp_sess_open().
  101. The first call to snmp_sess_init() initialises the SNMP Library,
  102. including the MIB parse trees, before any SNMP sessions are created.
  103. Applications that call snmp_sess_init() do not need to read MIBs
  104. nor setup environment variables to utilize the Library.
  105. After the struct snmp_session is setup, the thread must call
  106. snmp_sess_open() to create an SNMP session.  If at any time
  107. the thread must change the Session configuration,
  108. snmp_sess_session() returns the pointer to the internal configuration
  109. structure (a struct snmp_session, copied from snmp_sess_open).
  110. The thread can adjust parameters such as the session timeout
  111. or the community string with this returned struct snmp_session pointer.
  112. Changes to the remote or local port values have no effect on an opened Session.
  113.  
  114. The thread can build PDUs and bind variables to PDUs, as it performs its duties.
  115. The thread then calls snmp_sess_send() or snmp_sess_async_send() to build and send
  116. an SNMP APDU to the remote device. If a Get-Response-PDU is expected, the thread
  117. should call snmp_sess_synch_response() instead.
  118. When the thread is finished using the session, it must free the resources
  119. that the Library used to manage the session.
  120. Finally, the thread must call snmp_sess_close() to end the Session.
  121. Snmp_sess_init(), snmp_open(), and snmp_sess_open()
  122. must use the same calling parameter for a given Session.
  123. Other methods should use only the returned parameter from
  124. snmp_open() and snmp_sess_open() to access the opened SNMP Session.
  125. Error Processing
  126. Two calls were added : snmp_error() and snmp_sess_error() return the
  127. "errno" and "snmp_errno" values from the per session data, and a string
  128. that describes the errors that they represent.  The string must be freed
  129. by the caller.
  130. Use snmp_error() to process failures after Traditional API calls,
  131. or snmp_sess_error() to process failure after Single API calls.
  132. In the case where an SNMP session could not be opened,
  133. call snmp_error() using the struct snmp_session supplied to either snmp_open()
  134. or snmp_sess_open().
  135. The following variables and functions are obsolete and may create problems
  136. in a multi-threaded application :
  137.   int    snmp_errno
  138.   char * snmp_detail
  139.   snmp_set_detail()
  140.   snmp_api_errstring()
  141. Function Summary
  142.  
  143. The functions in the following table are functionally equivalent,
  144. with the exception of these behaviors:
  145. - The Traditional API manages many sessions
  146. - The Traditional API passes a struct snmp_session pointer,
  147.        and touches the Sessions list
  148. - The Single API manages only one session
  149. - The Single API passes an opaque pointer, and does not use Sessions list
  150.  
  151.   Traditional        Single                    Comment
  152.   ===========        ==============            =======
  153.   snmp_sess_init     snmp_sess_init            Call before either open
  154.   snmp_open          snmp_sess_open            Single not on Sessions list
  155.                      snmp_sess_session         Exposes snmp_session pointer
  156.   snmp_send          snmp_sess_send            Send one APDU
  157.   snmp_async_send    snmp_sess_async_send      Send one APDU with callback
  158.   snmp_select_info   snmp_sess_select_info     Which session(s) have input
  159.   snmp_read          snmp_sess_read            Read APDUs
  160.   snmp_timeout       snmp_sess_timeout         Check for timeout
  161.   snmp_close         snmp_sess_close           Single not on Sessions list
  162.  snmp_synch_response snmp_sess_synch_response  Send/receive one APDU
  163.   snmp_error         snmp_sess_error           Get library,system errno
  164. Example 1 : Traditional API use.
  165.     #include "snmp_api.h"
  166.       ...
  167.       int liberr, syserr;
  168.       char *errstr;
  169.       struct snmp_session Session, *sptr;
  170.       ...
  171.       snmp_sess_init(&Session);
  172.       Session.peername = "foo.bar.net";
  173.       sptr = snmp_open(&Session);
  174.       if (sptr == NULL) {
  175.           /* Error codes found in open calling argument */
  176.           snmp_error(&Session, &liberr, &syserr, &errstr);
  177.           printf("SNMP create error %s.n", errstr);
  178.           free(errstr);
  179.           return 0;
  180.       }
  181.       /* Pass sptr to snmp_error from here forward */
  182.       ...
  183.       /* Change the community name */
  184.       free(sptr->community);
  185.       sptr->community = strdup("public");
  186.       sptr->community_len = strlen("public");
  187.       ...
  188.       if (0 == snmp_send(sptr, pdu)) {
  189.           snmp_error(sptr, &liberr, &syserr, &errstr);
  190.           printf("SNMP write error %s.n", errstr);
  191.           free(errstr);
  192.           return 0;
  193.       }
  194.       snmp_close(sptr);
  195. Example 2 : Single API use.
  196.     #include "snmp_api.h"
  197.       ...
  198.       int liberr, syserr;
  199.       char *errstr;
  200.       void *sessp;  /* <-- an opaque pointer, not a struct pointer */
  201.       struct snmp_session Session, *sptr;
  202.       ...
  203.       snmp_sess_init(&Session);
  204.       Session.peername = "foo.bar.net";
  205.       sessp = snmp_sess_open(&Session);
  206.       if (sessp == NULL) {
  207.           /* Error codes found in open calling argument */
  208.           snmp_error(&Session, &liberr, &syserr, &errstr);
  209.           printf("SNMP create error %s.n", errstr);
  210.           free(errstr);
  211.           return 0;
  212.       }
  213.       sptr = snmp_sess_session(sessp); /* <-- get the snmp_session pointer */
  214.       /* Pass sptr to snmp_sess_error from here forward */
  215.       ...
  216.       /* Change the community name */
  217.       free(sptr->community);
  218.       sptr->community = strdup("public");
  219.       sptr->community_len = strlen("public");
  220.       ...
  221.       if (0 == snmp_sess_send(sessp, pdu)) {
  222.           snmp_sess_error(sessp, &liberr, &syserr, &errstr);
  223.           printf("SNMP write error %s.n", errstr);
  224.           free(errstr);
  225.           return 0;
  226.       }
  227.       snmp_sess_close(sessp);
  228.  
  229. Example 3. Differences Between Traditional API and Single API Usage
  230. 5a6
  231. >       void *sessp;  /* <-- an opaque pointer, not a struct pointer */
  232. 11,13c12,14
  233. <       sptr = snmp_open(&Session);
  234. <       if (sptr == NULL) {
  235. ---
  236. >       sessp = snmp_sess_open(&Session);
  237. >       if (sessp == NULL) {
  238. 19c20,22
  239. <       /* Pass sptr to snmp_error from here forward */
  240. ---
  241. >       sptr = snmp_sess_session(sessp); /* <-- get the snmp_session pointer */
  242. >       /* Pass sptr to snmp_sess_error from here forward */
  243. 26,27c29,30
  244. <       if (0 == snmp_send(sptr, pdu)) {
  245. <           snmp_error(sptr, &liberr, &syserr, &errstr);
  246. ---
  247. >       if (0 == snmp_sess_send(sessp, pdu)) {
  248. >           snmp_sess_error(sessp, &liberr, &syserr, &errstr);
  249. 33c36
  250. <       snmp_close(sptr);
  251. ---
  252. >       snmp_sess_close(sessp);
  253. Restrictions on Multi-threaded Use of the SNMP Library
  254.   1. Invoke SOCK_STARTUP or SOCK_CLEANUP from the main thread only.
  255.   2. The MIB parsing functions use global shared data and are not
  256.      multi-thread safe when the MIB tree is under construction.
  257.      Once the tree is built, the data can be safely referenced from
  258.      any thread.  There is no provision for freeing the MIB tree.
  259.      Suggestion: Read the MIB files before an SNMP session is created.
  260.      This can be accomplished by invoking snmp_sess_init from the main
  261.      thread and discarding the buffer which is initialised.
  262.   3. Invoke the SNMPv2p initialisation before an SNMP session is created,
  263.      for reasons similar to reading the MIB file.
  264.      The SNMPv2p structures should be available to all SNMP sessions.
  265.      CAUTION: These structures have not been tested in a multi-threaded
  266.      application.
  267.   4. Sessions created using the Single API do not interact with other
  268.      SNMP sessions.  If you choose to use Traditional API calls, call
  269.      them from a single thread.  The Library cannot reference an SNMP
  270.      session using both Traditional and Single API calls.
  271.   5. Using the callback mechanism for asynchronous response PDUs
  272.      requires additional caution in a multi-threaded application.
  273.      This means a callback function probably should probably not use
  274.      Single API calls to further process the session.
  275.   6. Each call to snmp_sess_open() creates an IDS.  Only a call to
  276.      snmp_sess_close() releases the resources used by the IDS.