]> git.ipfire.org Git - thirdparty/squid.git/blame - src/snmp/Forwarder.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / snmp / Forwarder.cc
CommitLineData
51ea0904 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
51ea0904 3 *
bbc27441
AJ
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.
51ea0904
CT
7 */
8
bbc27441
AJ
9/* DEBUG: section 49 SNMP Interface */
10
f7f3304a 11#include "squid.h"
51ea0904 12#include "base/TextException.h"
1b76e6c1 13#include "comm.h"
602d9612 14#include "CommCalls.h"
582c2af2 15#include "globals.h"
51ea0904 16#include "ipc/Port.h"
d6e3ad20
CT
17#include "snmp/Forwarder.h"
18#include "snmp/Request.h"
19#include "snmp/Response.h"
602d9612 20#include "snmp_core.h"
51ea0904 21
51ea0904
CT
22CBDATA_NAMESPACED_CLASS_INIT(Snmp, Forwarder);
23
51ea0904
CT
24Snmp::Forwarder::Forwarder(const Pdu& aPdu, const Session& aSession, int aFd,
25 const Ip::Address& anAddress):
4c218615 26 Ipc::Forwarder(new Request(KidIdentifier, Ipc::RequestId(), aPdu, aSession, aFd, anAddress), 2),
f53969cc 27 fd(aFd)
51ea0904 28{
bf95c10a 29 debugs(49, 5, "FD " << aFd);
51ea0904 30 Must(fd >= 0);
933a6aed 31 closer = asyncCall(49, 5, "Snmp::Forwarder::noteCommClosed",
51ea0904
CT
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
37void
ebaabe74 38Snmp::Forwarder::swanSong()
51ea0904
CT
39{
40 if (fd >= 0) {
aee3523a 41 if (closer != nullptr) {
51ea0904 42 comm_remove_close_handler(fd, closer);
aee3523a 43 closer = nullptr;
51ea0904
CT
44 }
45 fd = -1;
46 }
ebaabe74 47 Ipc::Forwarder::swanSong();
51ea0904
CT
48}
49
50/// called when the client socket gets closed by some external force
51void
52Snmp::Forwarder::noteCommClosed(const CommCloseCbParams& params)
53{
bf95c10a 54 debugs(49, 5, MYNAME);
51ea0904 55 Must(fd == params.fd);
2b6b1bcb 56 closer = nullptr;
51ea0904
CT
57 fd = -1;
58 mustStop("commClosed");
59}
60
61void
62Snmp::Forwarder::handleTimeout()
63{
64 sendError(SNMP_ERR_RESOURCEUNAVAILABLE);
65 Ipc::Forwarder::handleTimeout();
66}
67
68void
69Snmp::Forwarder::handleException(const std::exception& e)
70{
bf95c10a 71 debugs(49, 3, e.what());
2b6b1bcb 72 sendError(SNMP_ERR_GENERR);
51ea0904
CT
73 Ipc::Forwarder::handleException(e);
74}
75
76/// send error SNMP response
77void
78Snmp::Forwarder::sendError(int error)
79{
bf95c10a 80 debugs(49, 3, MYNAME);
2b6b1bcb
AR
81
82 if (fd < 0)
83 return; // client gone
84
51ea0904
CT
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
94void
4c218615 95Snmp::SendResponse(const Ipc::RequestId requestId, const Pdu &pdu)
51ea0904 96{
bf95c10a 97 debugs(49, 5, MYNAME);
51ea0904
CT
98 // snmpAgentResponse() can modify arg
99 Pdu tmp = pdu;
100 Snmp::Response response(requestId);
aee3523a 101 snmp_pdu* response_pdu = nullptr;
51ea0904
CT
102 try {
103 response_pdu = snmpAgentResponse(&tmp);
aee3523a 104 Must(response_pdu != nullptr);
51ea0904
CT
105 response.pdu = static_cast<Pdu&>(*response_pdu);
106 snmp_free_pdu(response_pdu);
107 } catch (const std::exception& e) {
bf95c10a 108 debugs(49, DBG_CRITICAL, e.what());
51ea0904
CT
109 response.pdu.command = SNMP_PDU_RESPONSE;
110 response.pdu.errstat = SNMP_ERR_GENERR;
111 }
112 Ipc::TypedMsgHdr message;
113 response.pack(message);
1ee292b7 114 Ipc::SendMessage(Ipc::Port::CoordinatorAddr(), message);
51ea0904 115}
f53969cc 116