]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/SharedListen.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / ipc / SharedListen.cc
CommitLineData
0d0bce6a 1/*
0d0bce6a 2 * DEBUG: section 54 Interprocess Communication
0d0bce6a
AR
3 */
4
f7f3304a 5#include "squid.h"
a67d2b2e 6#include "base/TextException.h"
602d9612 7#include "comm.h"
e0d28505 8#include "comm/Connection.h"
582c2af2 9#include "globals.h"
0d0bce6a 10#include "ipc/Kids.h"
602d9612
A
11#include "ipc/Messages.h"
12#include "ipc/Port.h"
0d0bce6a 13#include "ipc/SharedListen.h"
602d9612
A
14#include "ipc/StartListening.h"
15#include "ipc/TypedMsgHdr.h"
5bed43d6 16#include "tools.h"
0d0bce6a 17
3d41e53a
FC
18#include <map>
19
0d0bce6a
AR
20/// holds information necessary to handle JoinListen response
21class PendingOpenRequest
22{
23public:
24 Ipc::OpenListenerParams params; ///< actual comm_open_sharedListen() parameters
25 AsyncCall::Pointer callback; // who to notify
26};
27
28/// maps ID assigned at request time to the response callback
29typedef std::map<int, PendingOpenRequest> SharedListenRequestMap;
30static SharedListenRequestMap TheSharedListenRequestMap;
31
32static int
33AddToMap(const PendingOpenRequest &por)
34{
35 // find unused ID using linear seach; there should not be many entries
36 for (int id = 0; true; ++id) {
37 if (TheSharedListenRequestMap.find(id) == TheSharedListenRequestMap.end()) {
38 TheSharedListenRequestMap[id] = por;
39 return id;
40 }
41 }
42 assert(false); // not reached
43 return -1;
44}
45
46Ipc::OpenListenerParams::OpenListenerParams()
47{
e297be13 48 memset(this, 0, sizeof(*this));
0d0bce6a
AR
49}
50
51bool
52Ipc::OpenListenerParams::operator <(const OpenListenerParams &p) const
53{
54 if (sock_type != p.sock_type)
55 return sock_type < p.sock_type;
56
57 if (proto != p.proto)
58 return proto < p.proto;
59
60 // ignore flags and fdNote differences because they do not affect binding
61
62 return addr.compareWhole(p.addr) < 0;
63}
64
0d0bce6a
AR
65Ipc::SharedListenRequest::SharedListenRequest(): requestorId(-1), mapId(-1)
66{
67 // caller will then set public data members
68}
69
70Ipc::SharedListenRequest::SharedListenRequest(const TypedMsgHdr &hdrMsg)
71{
8822ebee
AR
72 hdrMsg.checkType(mtSharedListenRequest);
73 hdrMsg.getPod(*this);
0d0bce6a
AR
74}
75
76void Ipc::SharedListenRequest::pack(TypedMsgHdr &hdrMsg) const
77{
8822ebee
AR
78 hdrMsg.setType(mtSharedListenRequest);
79 hdrMsg.putPod(*this);
0d0bce6a
AR
80}
81
b72fb55d
CT
82Ipc::SharedListenResponse::SharedListenResponse(int aFd, int anErrNo, int aMapId):
83 fd(aFd), errNo(anErrNo), mapId(aMapId)
0d0bce6a
AR
84{
85}
86
87Ipc::SharedListenResponse::SharedListenResponse(const TypedMsgHdr &hdrMsg):
e34d49a9 88 fd(-1), errNo(0), mapId(-1)
0d0bce6a 89{
8822ebee
AR
90 hdrMsg.checkType(mtSharedListenResponse);
91 hdrMsg.getPod(*this);
b72fb55d 92 fd = hdrMsg.getFd();
e0d28505 93 // other conn details are passed in OpenListenerParams and filled out by SharedListenJoin()
0d0bce6a
AR
94}
95
96void Ipc::SharedListenResponse::pack(TypedMsgHdr &hdrMsg) const
97{
8822ebee
AR
98 hdrMsg.setType(mtSharedListenResponse);
99 hdrMsg.putPod(*this);
b72fb55d 100 hdrMsg.putFd(fd);
0d0bce6a
AR
101}
102
0d0bce6a 103void Ipc::JoinSharedListen(const OpenListenerParams &params,
5667a628 104 AsyncCall::Pointer &callback)
0d0bce6a
AR
105{
106 PendingOpenRequest por;
107 por.params = params;
108 por.callback = callback;
109
110 SharedListenRequest request;
111 request.requestorId = KidIdentifier;
112 request.params = por.params;
113 request.mapId = AddToMap(por);
114
115 debugs(54, 3, HERE << "getting listening FD for " << request.params.addr <<
5667a628 116 " mapId=" << request.mapId);
0d0bce6a
AR
117
118 TypedMsgHdr message;
119 request.pack(message);
120 SendMessage(coordinatorAddr, message);
121}
122
123void Ipc::SharedListenJoined(const SharedListenResponse &response)
124{
e0d28505 125 // Dont debugs c fully since only FD is filled right now.
b72fb55d 126 debugs(54, 3, HERE << "got listening FD " << response.fd << " errNo=" <<
5667a628 127 response.errNo << " mapId=" << response.mapId);
0d0bce6a
AR
128
129 Must(TheSharedListenRequestMap.find(response.mapId) != TheSharedListenRequestMap.end());
130 PendingOpenRequest por = TheSharedListenRequestMap[response.mapId];
131 Must(por.callback != NULL);
132 TheSharedListenRequestMap.erase(response.mapId);
133
b72fb55d
CT
134 StartListeningCb *cbd = dynamic_cast<StartListeningCb*>(por.callback->getDialer());
135 assert(cbd && cbd->conn != NULL);
136 Must(cbd && cbd->conn != NULL);
137 cbd->conn->fd = response.fd;
138
139 if (Comm::IsConnOpen(cbd->conn)) {
0d0bce6a 140 OpenListenerParams &p = por.params;
b72fb55d
CT
141 cbd->conn->local = p.addr;
142 cbd->conn->flags = p.flags;
e0d28505 143 // XXX: leave the comm AI stuff to comm_import_opened()?
0d0bce6a 144 struct addrinfo *AI = NULL;
4dd643d5 145 p.addr.getAddrInfo(AI);
0d0bce6a
AR
146 AI->ai_socktype = p.sock_type;
147 AI->ai_protocol = p.proto;
b72fb55d 148 comm_import_opened(cbd->conn, FdNote(p.fdNote), AI);
4dd643d5 149 Ip::Address::FreeAddrInfo(AI);
0d0bce6a
AR
150 }
151
0d0bce6a 152 cbd->errNo = response.errNo;
e0d28505 153 cbd->handlerSubscription = por.params.handlerSubscription;
0d0bce6a
AR
154 ScheduleCallHere(por.callback);
155}