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