]> git.ipfire.org Git - thirdparty/squid.git/blob - src/snmp/Forwarder.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / snmp / Forwarder.cc
1 /*
2 * Copyright (C) 1996-2023 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 "CommCalls.h"
15 #include "globals.h"
16 #include "ipc/Port.h"
17 #include "snmp/Forwarder.h"
18 #include "snmp/Request.h"
19 #include "snmp/Response.h"
20 #include "snmp_core.h"
21
22 CBDATA_NAMESPACED_CLASS_INIT(Snmp, Forwarder);
23
24 Snmp::Forwarder::Forwarder(const Pdu& aPdu, const Session& aSession, int aFd,
25 const Ip::Address& anAddress):
26 Ipc::Forwarder(new Request(KidIdentifier, Ipc::RequestId(), aPdu, aSession, aFd, anAddress), 2),
27 fd(aFd)
28 {
29 debugs(49, 5, "FD " << aFd);
30 Must(fd >= 0);
31 closer = asyncCall(49, 5, "Snmp::Forwarder::noteCommClosed",
32 CommCbMemFunT<Forwarder, CommCloseCbParams>(this, &Forwarder::noteCommClosed));
33 comm_add_close_handler(fd, closer);
34 }
35
36 /// removes our cleanup handler of the client connection socket
37 void
38 Snmp::Forwarder::swanSong()
39 {
40 if (fd >= 0) {
41 if (closer != nullptr) {
42 comm_remove_close_handler(fd, closer);
43 closer = nullptr;
44 }
45 fd = -1;
46 }
47 Ipc::Forwarder::swanSong();
48 }
49
50 /// called when the client socket gets closed by some external force
51 void
52 Snmp::Forwarder::noteCommClosed(const CommCloseCbParams& params)
53 {
54 debugs(49, 5, MYNAME);
55 Must(fd == params.fd);
56 closer = nullptr;
57 fd = -1;
58 mustStop("commClosed");
59 }
60
61 void
62 Snmp::Forwarder::handleTimeout()
63 {
64 sendError(SNMP_ERR_RESOURCEUNAVAILABLE);
65 Ipc::Forwarder::handleTimeout();
66 }
67
68 void
69 Snmp::Forwarder::handleException(const std::exception& e)
70 {
71 debugs(49, 3, e.what());
72 sendError(SNMP_ERR_GENERR);
73 Ipc::Forwarder::handleException(e);
74 }
75
76 /// send error SNMP response
77 void
78 Snmp::Forwarder::sendError(int error)
79 {
80 debugs(49, 3, MYNAME);
81
82 if (fd < 0)
83 return; // client gone
84
85 Snmp::Request& req = static_cast<Snmp::Request&>(*request);
86 req.pdu.command = SNMP_PDU_RESPONSE;
87 req.pdu.errstat = error;
88 u_char buffer[SNMP_REQUEST_SIZE];
89 int len = sizeof(buffer);
90 snmp_build(&req.session, &req.pdu, buffer, &len);
91 comm_udp_sendto(fd, req.address, buffer, len);
92 }
93
94 void
95 Snmp::SendResponse(const Ipc::RequestId requestId, const Pdu &pdu)
96 {
97 debugs(49, 5, MYNAME);
98 // snmpAgentResponse() can modify arg
99 Pdu tmp = pdu;
100 Snmp::Response response(requestId);
101 snmp_pdu* response_pdu = nullptr;
102 try {
103 response_pdu = snmpAgentResponse(&tmp);
104 Must(response_pdu != nullptr);
105 response.pdu = static_cast<Pdu&>(*response_pdu);
106 snmp_free_pdu(response_pdu);
107 } catch (const std::exception& e) {
108 debugs(49, DBG_CRITICAL, e.what());
109 response.pdu.command = SNMP_PDU_RESPONSE;
110 response.pdu.errstat = SNMP_ERR_GENERR;
111 }
112 Ipc::TypedMsgHdr message;
113 response.pack(message);
114 Ipc::SendMessage(Ipc::Port::CoordinatorAddr(), message);
115 }
116