diff options
Diffstat (limited to 'opentracker.c')
| -rw-r--r-- | opentracker.c | 42 |
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 */ | ||
| 193 | static void handle_accept(const int64_t serversocket, struct ot_workstruct *ws) { | 199 | static 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 | ||
