]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp/Inquirer.cc
dd6ed34f2c06258e66a257607cc53d1681ce4835
[thirdparty/squid.git] / src / snmp / Inquirer.cc
1 /*
2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 49 SNMP Interface */
10
11 #include "squid.h"
12 #include "base/TextException.h"
13 #include "comm.h"
14 #include "comm/Connection.h"
15 #include "CommCalls.h"
16 #include "ipc/UdsOp.h"
17 #include "snmp/Inquirer.h"
18 #include "snmp/Request.h"
19 #include "snmp/Response.h"
20 #include "snmp_core.h"
21
22 CBDATA_NAMESPACED_CLASS_INIT(Snmp, Inquirer);
23
24 Snmp::Inquirer::Inquirer(const Request& aRequest, const Ipc::StrandCoords& coords):
25 Ipc::Inquirer(aRequest.clone(), coords, 2),
26 aggrPdu(aRequest.pdu)
27 {
28 conn = new Comm::Connection;
29 conn->fd = aRequest.fd;
30 ImportFdIntoComm(conn, SOCK_DGRAM, IPPROTO_UDP, Ipc::fdnInSnmpSocket);
31
32 debugs(49, 5, HERE);
33 closer = asyncCall(49, 5, "Snmp::Inquirer::noteCommClosed",
34 CommCbMemFunT<Inquirer, CommCloseCbParams>(this, &Inquirer::noteCommClosed));
35 comm_add_close_handler(conn->fd, closer);
36
37 // forget client FD to avoid sending it to strands that may forget to close
38 if (Request *snmpRequest = dynamic_cast<Request*>(request.getRaw()))
39 snmpRequest->fd = -1;
40 }
41
42 /// closes our copy of the client connection socket
43 void
44 Snmp::Inquirer::cleanup()
45 {
46 if (Comm::IsConnOpen(conn)) {
47 if (closer != NULL) {
48 comm_remove_close_handler(conn->fd, closer);
49 closer = NULL;
50 }
51 conn->close();
52 }
53 conn = NULL;
54 }
55
56 void
57 Snmp::Inquirer::start()
58 {
59 debugs(49, 5, HERE);
60 Ipc::Inquirer::start();
61 Must(Comm::IsConnOpen(conn));
62 inquire();
63 }
64
65 void
66 Snmp::Inquirer::handleException(const std::exception& e)
67 {
68 aggrPdu.errstat = SNMP_ERR_GENERR;
69 Ipc::Inquirer::handleException(e);
70 }
71
72 bool
73 Snmp::Inquirer::aggregate(Response::Pointer aResponse)
74 {
75 Snmp::Response& response = static_cast<Snmp::Response&>(*aResponse);
76 bool error = response.pdu.errstat != SNMP_ERR_NOERROR;
77 if (error) {
78 aggrPdu = response.pdu;
79 } else {
80 aggrPdu.aggregate(response.pdu);
81 }
82 return !error;
83 }
84
85 /// called when the some external force closed our socket
86 void
87 Snmp::Inquirer::noteCommClosed(const CommCloseCbParams& params)
88 {
89 debugs(49, 5, HERE);
90 Must(!Comm::IsConnOpen(conn) || conn->fd == params.conn->fd);
91 conn = NULL;
92 mustStop("commClosed");
93 }
94
95 bool
96 Snmp::Inquirer::doneAll() const
97 {
98 return !writer && Ipc::Inquirer::doneAll();
99 }
100
101 void
102 Snmp::Inquirer::sendResponse()
103 {
104 debugs(49, 5, HERE);
105 aggrPdu.fixAggregate();
106 aggrPdu.command = SNMP_PDU_RESPONSE;
107 u_char buffer[SNMP_REQUEST_SIZE];
108 int len = sizeof(buffer);
109 Snmp::Request& req = static_cast<Snmp::Request&>(*request);
110 snmp_build(&req.session, &aggrPdu, buffer, &len);
111 comm_udp_sendto(conn->fd, req.address, buffer, len);
112 }
113