SharedListen.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 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 54 Interprocess Communication */
10
11#include "squid.h"
12#include "base/TextException.h"
13#include "comm.h"
14#include "comm/Connection.h"
15#include "globals.h"
16#include "ipc/Kids.h"
17#include "ipc/Messages.h"
18#include "ipc/Port.h"
19#include "ipc/SharedListen.h"
20#include "ipc/StartListening.h"
21#include "ipc/TypedMsgHdr.h"
22#include "tools.h"
23
24#include <list>
25#include <map>
26
29{
30public:
32 AsyncCall::Pointer callback; // who to notify
33};
34
36typedef std::map<Ipc::RequestId::Index, PendingOpenRequest> SharedListenRequestMap;
38
40typedef std::list<PendingOpenRequest> DelayedSharedListenRequests;
42
43// TODO: Encapsulate "Pending Request Map" logic shared by all RequestId users.
48{
49 static Ipc::RequestId::Index LastIndex = 0;
50 // TODO: Switch Ipc::RequestId::Index to uint64_t and drop these 0 checks.
51 if (++LastIndex == 0) // don't use zero value as an ID
52 ++LastIndex;
54 TheSharedListenRequestMap[LastIndex] = por;
55 return LastIndex;
56}
57
58bool
60{
61 if (sock_type != p.sock_type)
62 return sock_type < p.sock_type;
63
64 if (proto != p.proto)
65 return proto < p.proto;
66
67 // ignore flags and fdNote differences because they do not affect binding
68
69 return addr.compareWhole(p.addr) < 0;
70}
71
73 requestorId(KidIdentifier),
74 params(aParams),
75 mapId(aMapId)
76{
77 // caller will then set public data members
78}
79
81{
83 hdrMsg.getPod(*this);
84}
85
87{
89 hdrMsg.putPod(*this);
90}
91
92Ipc::SharedListenResponse::SharedListenResponse(const int aFd, const int anErrNo, const RequestId aMapId):
93 fd(aFd), errNo(anErrNo), mapId(aMapId)
94{
95}
96
98 fd(-1),
99 errNo(0)
100{
102 hdrMsg.getPod(*this);
103 fd = hdrMsg.getFd();
104 // other conn details are passed in OpenListenerParams and filled out by SharedListenJoin()
105}
106
108{
110 hdrMsg.putPod(*this);
111 // XXX: When we respond with an error, putFd() throws due to the negative fd
112 hdrMsg.putFd(fd);
113}
114
115static void
117{
119
120 debugs(54, 3, "getting listening FD for " << request.params.addr <<
121 " mapId=" << request.mapId);
122
123 Ipc::TypedMsgHdr message;
124 request.pack(message);
126}
127
128static void
130{
131 if (TheDelayedRequests.empty())
132 return; // no pending requests to resume
133
134 debugs(54, 3, "resuming with " << TheSharedListenRequestMap.size() <<
135 " active + " << TheDelayedRequests.size() << " delayed requests");
136
138 TheDelayedRequests.pop_front();
139}
140
141void
143{
145 por.params = params;
146 por.callback = cb;
147
148 const DelayedSharedListenRequests::size_type concurrencyLimit = 1;
149 if (TheSharedListenRequestMap.size() >= concurrencyLimit) {
150 debugs(54, 3, "waiting for " << TheSharedListenRequestMap.size() <<
151 " active + " << TheDelayedRequests.size() << " delayed requests");
152 TheDelayedRequests.push_back(por);
153 } else {
155 }
156}
157
159{
160 // Dont debugs c fully since only FD is filled right now.
161 debugs(54, 3, "got listening FD " << response.fd << " errNo=" <<
162 response.errNo << " mapId=" << response.mapId << " with " <<
163 TheSharedListenRequestMap.size() << " active + " <<
164 TheDelayedRequests.size() << " delayed requests");
165
166 Must(response.mapId);
167 const auto pori = TheSharedListenRequestMap.find(response.mapId.index());
168 Must(pori != TheSharedListenRequestMap.end());
169 auto por = pori->second;
170 Must(por.callback);
171 TheSharedListenRequestMap.erase(pori);
172
173 StartListeningCb *cbd = dynamic_cast<StartListeningCb*>(por.callback->getDialer());
174 assert(cbd && cbd->conn != nullptr);
175 Must(cbd && cbd->conn != nullptr);
176 cbd->conn->fd = response.fd;
177
178 if (Comm::IsConnOpen(cbd->conn)) {
179 OpenListenerParams &p = por.params;
180 cbd->conn->local = p.addr;
181 cbd->conn->flags = p.flags;
182 // XXX: leave the comm AI stuff to comm_import_opened()?
183 struct addrinfo *AI = nullptr;
184 p.addr.getAddrInfo(AI);
185 AI->ai_socktype = p.sock_type;
186 AI->ai_protocol = p.proto;
187 comm_import_opened(cbd->conn, FdNote(p.fdNote), AI);
189 }
190
191 cbd->errNo = response.errNo;
192 ScheduleCallHere(por.callback);
193
195}
196
#define ScheduleCallHere(call)
Definition: AsyncCall.h:164
std::map< Ipc::RequestId::Index, PendingOpenRequest > SharedListenRequestMap
maps ID assigned at request time to the response callback
Definition: SharedListen.cc:36
static DelayedSharedListenRequests TheDelayedRequests
Definition: SharedListen.cc:41
static void SendSharedListenRequest(const PendingOpenRequest &por)
static SharedListenRequestMap TheSharedListenRequestMap
Definition: SharedListen.cc:37
static void kickDelayedRequest()
static Ipc::RequestId::Index AddToMap(const PendingOpenRequest &por)
Definition: SharedListen.cc:47
std::list< PendingOpenRequest > DelayedSharedListenRequests
accumulates delayed requests until they are ready to be sent, in FIFO order
Definition: SharedListen.cc:40
#define Must(condition)
Definition: TextException.h:71
#define assert(EX)
Definition: assert.h:19
Ip::Address local
Definition: Connection.h:146
int compareWhole(const Ip::Address &rhs) const
Definition: Address.cc:724
static void FreeAddr(struct addrinfo *&ai)
Definition: Address.cc:686
void getAddrInfo(struct addrinfo *&ai, int force=AF_UNSPEC) const
Definition: Address.cc:599
"shared listen" is when concurrent processes are listening on the same fd
Definition: SharedListen.h:27
int fdNote
index into fd_note() comment strings
Definition: SharedListen.h:34
bool operator<(const OpenListenerParams &p) const
useful for map<>
Definition: SharedListen.cc:59
Ip::Address addr
will be memset and memcopied
Definition: SharedListen.h:37
static String CoordinatorAddr()
get the IPC message address for coordinator process
Definition: Port.cc:65
Index index() const
Definition: RequestId.h:45
unsigned int Index
Definition: RequestId.h:27
a request for a listen socket with given parameters
Definition: SharedListen.h:45
SharedListenRequest(const OpenListenerParams &, RequestId aMapId)
sender's constructor
Definition: SharedListen.cc:72
void pack(TypedMsgHdr &hdrMsg) const
prepare for sendmsg()
Definition: SharedListen.cc:86
a response to SharedListenRequest
Definition: SharedListen.h:61
void pack(TypedMsgHdr &hdrMsg) const
prepare for sendmsg()
SharedListenResponse(int fd, int errNo, RequestId aMapId)
sender's constructor
Definition: SharedListen.cc:92
int fd
opened listening socket or -1
Definition: SharedListen.h:71
RequestId mapId
to map future response to the requestor's callback
Definition: SharedListen.h:73
int errNo
errno value from comm_open_sharedListen() call
Definition: SharedListen.h:72
common API for all StartListening() callbacks
Comm::ConnectionPointer conn
opened listening socket
int errNo
errno value from the comm_open_listener() call
struct msghdr with a known type, fixed-size I/O and control buffers
Definition: TypedMsgHdr.h:35
int getFd() const
returns stored descriptor
Definition: TypedMsgHdr.cc:217
void putFd(int aFd)
stores descriptor
Definition: TypedMsgHdr.cc:196
void getPod(Pod &pod) const
load POD
Definition: TypedMsgHdr.h:118
void checkType(int aType) const
Definition: TypedMsgHdr.cc:94
void putPod(const Pod &pod)
store POD
Definition: TypedMsgHdr.h:128
void setType(int aType)
sets message type; use MessageType enum
Definition: TypedMsgHdr.cc:100
holds information necessary to handle JoinListen response
Definition: SharedListen.cc:29
AsyncCall::Pointer callback
Definition: SharedListen.cc:32
Ipc::OpenListenerParams params
actual comm_open_sharedListen() parameters
Definition: SharedListen.cc:31
void comm_import_opened(const Comm::ConnectionPointer &conn, const char *note, struct addrinfo *AI)
update Comm state after getting a comm_open() FD from another process
Definition: comm.cc:536
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
int KidIdentifier
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
void SendMessage(const String &toAddress, const TypedMsgHdr &message)
Definition: UdsOp.cc:188
void SharedListenJoined(const SharedListenResponse &response)
process Coordinator response to SharedListenRequest
void JoinSharedListen(const OpenListenerParams &, AsyncCall::Pointer &)
prepare and send SharedListenRequest to Coordinator
const char * FdNote(int fdNodeId)
converts FdNoteId into a string
Definition: FdNotes.cc:16
@ mtSharedListenRequest
Definition: Messages.h:28
@ mtSharedListenResponse
Definition: Messages.h:29
struct _request * request(char *urlin)
Definition: tcp-banger2.c:291

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors