summaryrefslogtreecommitdiff
path: root/opentracker.c
diff options
context:
space:
mode:
Diffstat (limited to 'opentracker.c')
-rw-r--r--opentracker.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/opentracker.c b/opentracker.c
index ec92fe0..b47759e 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -190,29 +190,45 @@ static void handle_write(const int64_t sock) {
190 http_close(sock); 190 http_close(sock);
191} 191}
192 192
193/* The fast path, assuming that the complete request has usually arrived by the time a
194 connection is accepted, so it is answered here outside the event loop. The more load
195 a tracker has, the more likely it is that by the time it accepts, the roundtrip to
196 the peer has completed.
197 If the request could not be completely handled, the stack cookie is promoted to heap
198 and the connection handed over to the event loop to finish */
193static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { 199static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) {
194 struct http_data *cookie; 200 int64_t sock;
195 int64_t sock; 201 ot_ip6 ip;
196 ot_ip6 ip; 202 uint16_t port;
197 uint16_t port;
198 203
199 while ((sock = socket_accept(serversocket, ip, &port)) != -1) { 204 while ((sock = socket_accept(serversocket, ip, &port)) != -1) {
205 struct http_data cookie;
206 uint32_t generation;
200 207
201 if (!(cookie = (struct http_data *)calloc(1, sizeof(struct http_data)))) { 208 memset(&cookie, 0, sizeof(cookie));
202 close((int)sock); 209 memcpy(cookie.ip, ip, sizeof(ot_ip6));
203 continue; 210 cookie.interest = EVENT_IN;
204 } 211 cookie.flag = STRUCT_HTTP_FLAG_ONSTACK;
205 memcpy(cookie->ip, ip, sizeof(ot_ip6));
206 cookie->interest = EVENT_IN;
207 212
208 if (event_add((int)sock, EVENT_IN, fdstate_open(sock, cookie, time_future_seconds(OT_CLIENT_TIMEOUT))) == -1) { 213 generation = fdstate_open(sock, &cookie, time_future_seconds(OT_CLIENT_TIMEOUT));
214 if (!fdstate_claim((int)sock, generation)) {
209 fdstate_close(sock); 215 fdstate_close(sock);
210 free(cookie); 216 event_close((int)sock);
211 close((int)sock);
212 continue; 217 continue;
213 } 218 }
214 219
215 stats_issue_event(ws, EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); 220 stats_issue_event(ws, EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip);
221
222 handle_read(sock, ws);
223
224 /* Gone already if it was answered and closed inline */
225 if (fdstate_generation((int)sock) != generation)
226 continue;
227
228 if (http_adopt(sock, &cookie) == -1)
229 http_close(sock);
230 else
231 fdstate_release((int)sock);
216 } 232 }
217} 233}
218 234