catalinux / Conn (public) (License: LGPLv2) (since 2016-03-01) (hash sha1)
Net library for easy building ipv4/ipv6 network daemons/clients
List of commits:
Subject Hash Author Date (UTC)
Lots of bulk changes to work-around C pointer change. bf3d2ae7af927b3624c4685c72ca6fa812bca640 Catalin(ux) M. BOIE 2009-09-17 14:47:19
Bumped version to 1.0.24. 77e8249758effc45a86d66f8edc5973f11a5b6f9 Catalin(ux) M. BOIE 2009-09-17 12:20:16
Allow chg function to fail. Problem needs more thinking. a01999f729b0afd5891dcd538c91e564c274ce69 Catalin(ux) M. BOIE 2009-09-17 12:19:24
Done some optimizations for buffer expanding. 0fa9c81dc4ded2296c1825c5ccd3b264995962aa Catalin(ux) M. BOIE 2009-09-17 12:02:46
Do not wrongly set connection type to P2P! ccb997058dedaa139cf12e30eb8547f2dd99993e Catalin(ux) M. BOIE 2009-09-17 11:17:31
Bumped version to 1.0.23. b79fc6931982e2389f1b29b91d2386eaa779c143 Catalin(ux) M. BOIE 2009-09-17 09:43:00
Duilder updates. 534af0dbaf993201b588d463f58e64401ccc7d85 Catalin(ux) M. BOIE 2009-09-17 09:42:45
Fixed triggers. 6a95b877268bbf4522c53398e29c3dab1a8f22d1 Catalin(ux) M. BOIE 2009-09-17 09:41:44
Bumped version to 1.0.22. 0efd6d2a3787fe9a3f2c963bbcc85c95d44b954a Catalin(ux) M. BOIE 2009-09-02 16:23:25
Updated duilder. 8bfb064fb40b962a0ed18f3af21fbfd0289672dd Catalin(ux) M. BOIE 2009-09-02 15:48:51
Added latency reporting. 218047bf22e2804a585703751b51c6b2d54c59ad Catalin(ux) M. BOIE 2009-09-02 16:29:44
TODO in/out. d56467202a5a6823716ae3e6e3e15cee93fe86d1 Catalin(ux) M. BOIE 2009-09-02 16:29:07
Ignore EMPTY state. ef0dbfef5db779a9bb3cb1782e00c62d1abc1b07 Catalin(ux) M. BOIE 2009-08-31 20:54:13
Increment Conn_pending only on success. e2bacc2941cb07836973f881d060e05018f28c62 Catalin(ux) M. BOIE 2009-08-31 20:53:53
Cosmetic changes. f09c89986ade60ff5f9a79f6080783acff11c3d5 Catalin(ux) M. BOIE 2009-08-31 20:53:33
Set start values for enums. f2d6b05dce0e058323101a4d6f159c0c4172941a Catalin(ux) M. BOIE 2009-08-31 20:52:41
Call close callback, even if state is ERROR. 58e96228277c188b7b072496e337be9c94f56eb1 Catalin(ux) M. BOIE 2009-08-31 20:52:17
Added Conn_work_to_do to signal when we can exit. 492d960bf3e5b3718fe69ffc8ef30fbe344a805f Catalin(ux) M. BOIE 2009-08-31 20:50:56
Splited reporting of error types. 2d28a3be0ebb1f5e3f548d2523ac591af7dee3b9 Catalin(ux) M. BOIE 2009-08-31 20:08:54
Conn_commit will return error, so, do not call error callback. c97f8be6cfd55c32d78e62a30375d7c014dc0e0a Catalin(ux) M. BOIE 2009-08-31 20:08:17
Commit bf3d2ae7af927b3624c4685c72ca6fa812bca640 - Lots of bulk changes to work-around C pointer change.
Author: Catalin(ux) M. BOIE
Author date (UTC): 2009-09-17 14:47
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2009-09-17 14:47
Parent(s): 77e8249758effc45a86d66f8edc5973f11a5b6f9
Signing key:
Tree: dfbce4ce5080fc7adda078ffbcd268ba7acf9b19
File Lines added Lines deleted
Conn.c 241 241
Conn_engine_core.c 231 163
Conn_engine_core.h 12 12
Conn_engine_epoll.c 3 5
Conn_engine_epoll.h 1 1
Conn_engine_poll.c 7 7
Conn_engine_poll.h 1 1
TODO 1 0
examples/Makefile 4 1
File Conn.c changed (mode: 100644) (index 45312dc..c9b129c)
... ... static int (*Conn_engine_grow)(unsigned int);
24 24 static int (*Conn_engine_add_obj)(struct Conn *); static int (*Conn_engine_add_obj)(struct Conn *);
25 25 static int (*Conn_engine_del_obj)(struct Conn *); static int (*Conn_engine_del_obj)(struct Conn *);
26 26 static int (*Conn_engine_chg_obj)(struct Conn *); static int (*Conn_engine_chg_obj)(struct Conn *);
27 static int (*Conn_engine_poll)(int, void (*cb)(struct Conn *C, const int revents));
27 static int (*Conn_engine_poll)(int, void (*cb)(const unsigned int slot, const int revents));
28 28 static int (*Conn_engine_move_slot)(const unsigned int dst, static int (*Conn_engine_move_slot)(const unsigned int dst,
29 29 const unsigned int src); const unsigned int src);
30 30
 
... ... int Conn_init(const unsigned int max)
214 214 int Conn_shutdown(void) int Conn_shutdown(void)
215 215 { {
216 216 int ret; int ret;
217 unsigned int i;
217 unsigned int slot;
218 218
219 219 Conn_inited = 0; Conn_inited = 0;
220 220
 
... ... int Conn_shutdown(void)
223 223 return ret; return ret;
224 224
225 225 /* Free all buffers */ /* Free all buffers */
226 for (i = 0; i < Conn_allocated - 1; i++) {
227 if (Conns[i].ibuf)
228 free(Conns[i].ibuf);
229 if (Conns[i].obuf)
230 free(Conns[i].obuf);
226 for (slot = 0; slot < Conn_allocated - 1; slot++) {
227 if (Conns[slot].ibuf)
228 free(Conns[slot].ibuf);
229 if (Conns[slot].obuf)
230 free(Conns[slot].obuf);
231 231 } }
232 232
233 233 free(Conns); free(Conns);
 
... ... int Conn_shutdown(void)
237 237
238 238 int Conn_enqueue(struct Conn *C, void *buf, const size_t count) int Conn_enqueue(struct Conn *C, void *buf, const size_t count)
239 239 { {
240 unsigned int r;
240 unsigned int r, slot;
241 241 char *dump; char *dump;
242 242
243 243 if (C == NULL) { if (C == NULL) {
 
... ... int Conn_enqueue(struct Conn *C, void *buf, const size_t count)
245 245 return -1; return -1;
246 246 } }
247 247
248 slot = C->slot;
249
248 250 if (Conn_level >= 10) { if (Conn_level >= 10) {
249 251 dump = Conn_dump(buf, count); dump = Conn_dump(buf, count);
250 252 Log(0, "\tTry to enqueue %d bytes to slot=%u, id=%llu [%s]...\n", Log(0, "\tTry to enqueue %d bytes to slot=%u, id=%llu [%s]...\n",
251 count, C->slot, C->id, dump);
253 count, slot, Conns[slot].id, dump);
252 254 free(dump); free(dump);
253 255 } }
254 256
255 if (C->obuf_size - C->obuf_tail < count) {
256 r = Conn_try_expand_buf(C, 0, count);
257 if (Conns[slot].obuf_size - Conns[slot].obuf_tail < count) {
258 r = Conn_try_expand_buf(slot, 0, count);
257 259 if (r != 0) if (r != 0)
258 260 return -1; return -1;
259 261 } }
260 262
261 memcpy(C->obuf + C->obuf_tail, buf, count);
262 C->obuf_tail += count;
263 memcpy(Conns[slot].obuf + Conns[slot].obuf_tail, buf, count);
264 Conns[slot].obuf_tail += count;
263 265
264 C->events |= CONN_POLLOUT;
265 Conn_engine_chg_obj(C);
266 Conns[slot].events |= CONN_POLLOUT;
267 Conn_engine_chg_obj(&Conns[slot]);
266 268
267 269 return count; return count;
268 270 } }
269 271
270 static void Conn_free_intern(struct Conn *C)
272 static void Conn_free_intern(const unsigned int slot)
271 273 { {
272 274 Log(11, "%s: Cleaning-up id %llu (slot %u) in state %s [%s]...\n", Log(11, "%s: Cleaning-up id %llu (slot %u) in state %s [%s]...\n",
273 __FUNCTION__, C->id, C->slot, Conn_state(C), Conn_errno(C));
275 __FUNCTION__, Conns[slot].id, slot, Conn_state(&Conns[slot]),
276 Conn_errno(&Conns[slot]));
274 277
275 278 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
276 "%s", Conn_errno(C));
279 "%s", Conn_errno(&Conns[slot]));
277 280
278 if (C->error_state != CONN_ERROR_USERREQ)
279 Conn_error_raise(C, 0);
281 if (Conns[slot].error_state != CONN_ERROR_USERREQ)
282 Conn_error_raise(slot, 0);
280 283
281 if ((C->state == CONN_STATE_OPEN)
282 || (C->state == CONN_STATE_LISTEN)
283 || (C->state == CONN_STATE_ERROR)) {
284 if (C->cb_close)
285 C->cb_close(C);
284 if ((Conns[slot].state == CONN_STATE_OPEN)
285 || (Conns[slot].state == CONN_STATE_LISTEN)
286 || (Conns[slot].state == CONN_STATE_ERROR)) {
287 if (Conns[slot].cb_close)
288 Conns[slot].cb_close(&Conns[slot]);
286 289 else if (Conn_close_cb) else if (Conn_close_cb)
287 Conn_close_cb(C);
290 Conn_close_cb(&Conns[slot]);
288 291 } }
289 292
290 if (C->fd > -1) {
291 Conn_engine_del_obj(C);
292 close(C->fd);
293 C->fd = -1;
293 if (Conns[slot].fd > -1) {
294 Conn_engine_del_obj(&Conns[slot]);
295 close(Conns[slot].fd);
296 Conns[slot].fd = -1;
294 297 } }
295 298
296 299 /* Reset tsend, else we enter in a timeout error loop */ /* Reset tsend, else we enter in a timeout error loop */
297 C->tsend.tv_sec = 0;
298 C->tsend.tv_usec = 0;
300 Conns[slot].tsend.tv_sec = 0;
301 Conns[slot].tsend.tv_usec = 0;
299 302
300 303 /* Reset the connection attempt time */ /* Reset the connection attempt time */
301 C->conn_syn.tv_sec = 0;
302 C->conn_syn.tv_usec = 0;
304 Conns[slot].conn_syn.tv_sec = 0;
305 Conns[slot].conn_syn.tv_usec = 0;
303 306
304 307 /* Misc */ /* Misc */
305 C->error_state = 0;
308 Conns[slot].error_state = 0;
306 309
307 if (C->flags & CONN_FLAGS_AUTO_RECONNECT) {
308 C->tryat = Conn_now.tv_sec + C->delay;
309 C->state = CONN_STATE_CONNECT_0;
310 if (Conns[slot].flags & CONN_FLAGS_AUTO_RECONNECT) {
311 Conns[slot].tryat = Conn_now.tv_sec + Conns[slot].delay;
312 Conns[slot].state = CONN_STATE_CONNECT_0;
310 313
311 C->ibuf_head = 0;
312 C->ibuf_tail = 0;
314 Conns[slot].ibuf_head = 0;
315 Conns[slot].ibuf_tail = 0;
313 316
314 C->obuf_head = 0;
315 C->obuf_tail = 0;
317 Conns[slot].obuf_head = 0;
318 Conns[slot].obuf_tail = 0;
316 319
317 320 Conn_pending++; Conn_pending++;
318 321 } else { } else {
319 C->type = CONN_TYPE_UNK;
320 C->state = CONN_STATE_FREE;
322 Conns[slot].type = CONN_TYPE_UNK;
323 Conns[slot].state = CONN_STATE_FREE;
321 324
322 325 /* Allow connections */ /* Allow connections */
323 326 Conn_accept_is_allowed = 1; Conn_accept_is_allowed = 1;
 
... ... static int Conn_grow(void)
365 368 */ */
366 369 struct Conn *Conn_alloc(void) struct Conn *Conn_alloc(void)
367 370 { {
368 struct Conn *C;
369 371 unsigned int growok; unsigned int growok;
370 372 void *p; void *p;
373 unsigned int slot;
371 374
372 375 Log(10, "%s() Conn_no=%d Conn_max=%d\n", Log(10, "%s() Conn_no=%d Conn_max=%d\n",
373 376 __FUNCTION__, __FUNCTION__,
 
... ... struct Conn *Conn_alloc(void)
391 394 if (Conn_no > Conn_max_reached) if (Conn_no > Conn_max_reached)
392 395 Conn_max_reached = Conn_no; Conn_max_reached = Conn_no;
393 396
394 C = &Conns[Conn_no];
395 C->slot = Conn_no;
397 slot = Conn_no;
398 Conns[slot].slot = slot;
396 399
397 C->type = CONN_TYPE_UNK;
398 C->state = CONN_STATE_EMPTY;
400 Conns[slot].type = CONN_TYPE_UNK;
401 Conns[slot].state = CONN_STATE_EMPTY;
399 402
400 if (C->ibuf_size < Conn_default_ibuf) {
401 p = realloc(C->ibuf, Conn_default_ibuf);
403 if (Conns[slot].ibuf_size < Conn_default_ibuf) {
404 p = realloc(Conns[slot].ibuf, Conn_default_ibuf);
402 405 if (p == NULL) { if (p == NULL) {
403 406 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
404 407 "Memory allocation error2!"); "Memory allocation error2!");
405 408 return NULL; return NULL;
406 409 } }
407 C->ibuf = p;
408 C->ibuf_size = Conn_default_ibuf;
410 Conns[slot].ibuf = p;
411 Conns[slot].ibuf_size = Conn_default_ibuf;
409 412 } }
410 C->ibuf_head = 0;
411 C->ibuf_tail = 0;
413 Conns[slot].ibuf_head = 0;
414 Conns[slot].ibuf_tail = 0;
412 415
413 if (C->obuf_size < Conn_default_obuf) {
414 p = realloc(C->obuf, Conn_default_obuf);
416 if (Conns[slot].obuf_size < Conn_default_obuf) {
417 p = realloc(Conns[slot].obuf, Conn_default_obuf);
415 418 if (p == NULL) { if (p == NULL) {
416 419 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
417 420 "Memory allocation error3!"); "Memory allocation error3!");
418 421 return NULL; return NULL;
419 422 } }
420 C->obuf = p;
421 C->obuf_size = Conn_default_obuf;
423 Conns[slot].obuf = p;
424 Conns[slot].obuf_size = Conn_default_obuf;
422 425 } }
423 C->obuf_head = 0;
424 C->obuf_tail = 0;
426 Conns[slot].obuf_head = 0;
427 Conns[slot].obuf_tail = 0;
425 428
426 C->trecv = Conn_now;
429 Conns[slot].trecv = Conn_now;
427 430
428 C->bi = 0;
429 C->bo = 0;
430 C->private = NULL;
431 Conns[slot].bi = 0;
432 Conns[slot].bo = 0;
433 Conns[slot].private = NULL;
431 434
432 435 /* Reset syn time */ /* Reset syn time */
433 C->conn_syn.tv_sec = 0;
434 C->conn_syn.tv_usec = 0;
436 Conns[slot].conn_syn.tv_sec = 0;
437 Conns[slot].conn_syn.tv_usec = 0;
435 438
436 439 /* bandwidth */ /* bandwidth */
437 C->band_width = 0;
438 C->band_factor = 0;
439 C->band_tokens = 0;
440 C->band_lasttime = Conn_now;
440 Conns[slot].band_width = 0;
441 Conns[slot].band_factor = 0;
442 Conns[slot].band_tokens = 0;
443 Conns[slot].band_lasttime = Conn_now;
441 444
442 C->fd = -1;
443 C->events = 0;
444 C->revents = 0;
445 Conns[slot].fd = -1;
446 Conns[slot].events = 0;
447 Conns[slot].revents = 0;
445 448
446 C->flags = 0;
449 Conns[slot].flags = 0;
447 450
448 C->start = Conn_now.tv_sec;
451 Conns[slot].start = Conn_now.tv_sec;
449 452
450 C->id = Conn_id++;
453 Conns[slot].id = Conn_id++;
451 454
452 455 Conn_no++; Conn_no++;
453 456 /* Conn_work_to_do will not be incremented here, only in commit! */ /* Conn_work_to_do will not be incremented here, only in commit! */
454 457
455 458 Log(10, "\tFound free slot=%u, id=%llu. Now Conn_no=%d\n", Log(10, "\tFound free slot=%u, id=%llu. Now Conn_no=%d\n",
456 C->slot, C->id, Conn_no);
459 slot, Conns[slot].id, Conn_no);
457 460
458 461 if (Conn_no == Conn_max) if (Conn_no == Conn_max)
459 462 Conn_accept_is_allowed = 0; Conn_accept_is_allowed = 0;
460 463
461 return C;
464 return &Conns[slot];
462 465 } }
463 466
464 467 int Conn_set_socket_domain(struct Conn *C, const int domain) int Conn_set_socket_domain(struct Conn *C, const int domain)
 
... ... int Conn_commit(struct Conn *C)
522 525 int sock_len = 0, bind_sock_len = 0; int sock_len = 0, bind_sock_len = 0;
523 526 int do_bind = 1, do_listen = 1, do_connect = 0; int do_bind = 1, do_listen = 1, do_connect = 0;
524 527 int first_state; int first_state;
528 unsigned int slot;
529
530 slot = C->slot;
525 531
526 532 /* Try to figure what kind of socket is: client or master */ /* Try to figure what kind of socket is: client or master */
527 if (C->type == CONN_TYPE_UNK) {
528 if (strlen(C->addr) > 0) {
529 C->type = CONN_TYPE_P2P;
533 if (Conns[slot].type == CONN_TYPE_UNK) {
534 if (strlen(Conns[slot].addr) > 0) {
535 Conns[slot].type = CONN_TYPE_P2P;
530 536 do_listen = 0; do_listen = 0;
531 537 do_connect = 1; do_connect = 1;
532 538 } else { } else {
533 C->type = CONN_TYPE_MASTER;
534 if (strlen(C->bind_addr) == 0) {
535 switch (C->sock_domain) {
539 Conns[slot].type = CONN_TYPE_MASTER;
540 if (strlen(Conns[slot].bind_addr) == 0) {
541 switch (Conns[slot].sock_domain) {
536 542 case PF_INET: case PF_INET:
537 snprintf(C->bind_addr, sizeof(C->bind_addr),
543 snprintf(Conns[slot].bind_addr, sizeof(Conns[slot].bind_addr),
538 544 "0.0.0.0"); break; "0.0.0.0"); break;
539 545 case PF_INET6: case PF_INET6:
540 snprintf(C->bind_addr, sizeof(C->bind_addr),
546 snprintf(Conns[slot].bind_addr, sizeof(Conns[slot].bind_addr),
541 547 "::"); break; "::"); break;
542 548 } }
543 549 } }
544 550 } }
545 551 } }
546 552
547 switch (C->sock_domain) {
553 switch (Conns[slot].sock_domain) {
548 554 case PF_INET: case PF_INET:
549 555 /* for connection socket */ /* for connection socket */
550 if (strlen(C->addr) > 0) {
556 if (strlen(Conns[slot].addr) > 0) {
551 557 memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
552 558 sa.sin_family = AF_INET; sa.sin_family = AF_INET;
553 ret = inet_pton(AF_INET, C->addr, &sa.sin_addr);
559 ret = inet_pton(AF_INET, Conns[slot].addr, &sa.sin_addr);
554 560 if (ret < 0) { if (ret < 0) {
555 561 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
556 "inet_pton(%s) failed", C->addr);
562 "inet_pton(%s) failed", Conns[slot].addr);
557 563 return -1; return -1;
558 564 } }
559 sa.sin_port = htons(C->port);
565 sa.sin_port = htons(Conns[slot].port);
560 566 psa = (struct sockaddr *) &sa; psa = (struct sockaddr *) &sa;
561 567 sock_len = sizeof(sa); sock_len = sizeof(sa);
562 568 } }
563 569
564 570 /* for binding socket */ /* for binding socket */
565 if (strlen(C->bind_addr) > 0) {
571 if (strlen(Conns[slot].bind_addr) > 0) {
566 572 memset(&bind_sa, 0, sizeof(bind_sa)); memset(&bind_sa, 0, sizeof(bind_sa));
567 573 bind_sa.sin_family = AF_INET; bind_sa.sin_family = AF_INET;
568 ret = inet_pton(AF_INET, C->bind_addr, &bind_sa.sin_addr);
574 ret = inet_pton(AF_INET, Conns[slot].bind_addr, &bind_sa.sin_addr);
569 575 if (ret < 0) { if (ret < 0) {
570 576 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
571 "inet_pton(%s) failed", C->bind_addr);
577 "inet_pton(%s) failed", Conns[slot].bind_addr);
572 578 return -1; return -1;
573 579 } }
574 bind_sa.sin_port = htons(C->bind_port);
580 bind_sa.sin_port = htons(Conns[slot].bind_port);
575 581 bind_psa = (struct sockaddr *) &bind_sa; bind_psa = (struct sockaddr *) &bind_sa;
576 582 bind_sock_len = sizeof(bind_sa); bind_sock_len = sizeof(bind_sa);
577 583 } }
578 584
579 if (C->sock_type == SOCK_STREAM) {
585 if (Conns[slot].sock_type == SOCK_STREAM) {
580 586 first_state = CONN_STATE_LISTEN; first_state = CONN_STATE_LISTEN;
581 } else if (C->sock_type == SOCK_DGRAM) {
587 } else if (Conns[slot].sock_type == SOCK_DGRAM) {
582 588 do_listen = 0; do_listen = 0;
583 589 first_state = CONN_STATE_OPEN; first_state = CONN_STATE_OPEN;
584 590 } }
 
... ... int Conn_commit(struct Conn *C)
586 592
587 593 case PF_INET6: case PF_INET6:
588 594 /* for connection socket */ /* for connection socket */
589 if (strlen(C->addr) > 0) {
595 if (strlen(Conns[slot].addr) > 0) {
590 596 memset(&sa6, 0, sizeof(sa6)); memset(&sa6, 0, sizeof(sa6));
591 597 sa6.sin6_family = AF_INET6; sa6.sin6_family = AF_INET6;
592 ret = inet_pton(AF_INET6, C->addr, &sa6.sin6_addr);
598 ret = inet_pton(AF_INET6, Conns[slot].addr, &sa6.sin6_addr);
593 599 if (ret < 0) { if (ret < 0) {
594 600 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
595 "inet_pton(%s) failed", C->addr);
601 "inet_pton(%s) failed", Conns[slot].addr);
596 602 return -1; return -1;
597 603 } }
598 sa6.sin6_port = htons(C->port);
604 sa6.sin6_port = htons(Conns[slot].port);
599 605 psa = (struct sockaddr *) &sa6; psa = (struct sockaddr *) &sa6;
600 606 sock_len = sizeof(sa6); sock_len = sizeof(sa6);
601 607 } }
602 608
603 609 /* for binding socket */ /* for binding socket */
604 if (strlen(C->bind_addr) > 0) {
610 if (strlen(Conns[slot].bind_addr) > 0) {
605 611 memset(&bind_sa6, 0, sizeof(bind_sa6)); memset(&bind_sa6, 0, sizeof(bind_sa6));
606 612 bind_sa6.sin6_family = AF_INET6; bind_sa6.sin6_family = AF_INET6;
607 ret = inet_pton(AF_INET6, C->bind_addr, &bind_sa6.sin6_addr);
613 ret = inet_pton(AF_INET6, Conns[slot].bind_addr, &bind_sa6.sin6_addr);
608 614 if (ret < 0) { if (ret < 0) {
609 615 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
610 "inet_pton(%s) failed", C->bind_addr);
616 "inet_pton(%s) failed", Conns[slot].bind_addr);
611 617 return -1; return -1;
612 618 } }
613 bind_sa6.sin6_port = htons(C->bind_port);
619 bind_sa6.sin6_port = htons(Conns[slot].bind_port);
614 620 bind_psa = (struct sockaddr *) &bind_sa6; bind_psa = (struct sockaddr *) &bind_sa6;
615 621 bind_sock_len = sizeof(bind_sa6); bind_sock_len = sizeof(bind_sa6);
616 622 } }
617 623
618 if (C->sock_type == SOCK_STREAM) {
624 if (Conns[slot].sock_type == SOCK_STREAM) {
619 625 first_state = CONN_STATE_LISTEN; first_state = CONN_STATE_LISTEN;
620 } else if (C->sock_type == SOCK_DGRAM) {
626 } else if (Conns[slot].sock_type == SOCK_DGRAM) {
621 627 do_listen = 0; do_listen = 0;
622 628 first_state = CONN_STATE_OPEN; first_state = CONN_STATE_OPEN;
623 629 } }
 
... ... int Conn_commit(struct Conn *C)
631 637
632 638 default: default:
633 639 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
634 "Invalid domain [%d]!", C->sock_domain);
640 "Invalid domain [%d]!", Conns[slot].sock_domain);
635 641 return -1; return -1;
636 642 } }
637 643
638 C->fd = socket(C->sock_domain, C->sock_type, C->sock_protocol);
639 if (C->fd == -1) {
644 Conns[slot].fd = socket(Conns[slot].sock_domain, Conns[slot].sock_type, Conns[slot].sock_protocol);
645 if (Conns[slot].fd == -1) {
640 646 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
641 647 "Cannot create socket (%s, %s, %s) [%s]", "Cannot create socket (%s, %s, %s) [%s]",
642 648 Conn_domain(C), Conn_type(C), Conn_domain(C), Conn_type(C),
 
... ... int Conn_commit(struct Conn *C)
645 651 return -1; return -1;
646 652 } }
647 653
648 Conn_setnonblock(C->fd);
654 Conn_setnonblock(Conns[slot].fd);
649 655
650 if (C->sock_domain == PF_INET6) {
656 if (Conns[slot].sock_domain == PF_INET6) {
651 657 #ifndef IPV6_V6ONLY #ifndef IPV6_V6ONLY
652 658 #define IPV6_V6ONLY 26 #define IPV6_V6ONLY 26
653 659 #endif #endif
654 660 i = 1; i = 1;
655 setsockopt(C->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&i, sizeof(i));
661 setsockopt(Conns[slot].fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&i, sizeof(i));
656 662 } }
657 663
658 if (strlen(C->bind_addr) > 0) {
664 if (strlen(Conns[slot].bind_addr) > 0) {
659 665 i = 1; i = 1;
660 setsockopt(C->fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
666 setsockopt(Conns[slot].fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
661 667
662 ret = bind(C->fd, bind_psa, bind_sock_len);
668 ret = bind(Conns[slot].fd, bind_psa, bind_sock_len);
663 669 if (ret < 0) { if (ret < 0) {
664 670 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
665 671 "Cannot bind on %s/%d [%s]", "Cannot bind on %s/%d [%s]",
666 C->bind_addr, C->bind_port, strerror(errno));
672 Conns[slot].bind_addr, Conns[slot].bind_port, strerror(errno));
667 673 goto out_free_fd; goto out_free_fd;
668 674 } }
669 675 } }
670 676
671 C->events = CONN_POLLIN;
672 C->revents = 0;
677 Conns[slot].events = CONN_POLLIN;
678 Conns[slot].revents = 0;
673 679
674 680 if (do_listen == 1) if (do_listen == 1)
675 listen(C->fd, 4096);
681 listen(Conns[slot].fd, 4096);
676 682
677 683 if (do_connect == 1) { if (do_connect == 1) {
678 684 /*TODO:replace connect_a with OPEN?! */ /*TODO:replace connect_a with OPEN?! */
679 685 first_state = CONN_STATE_CONNECT_a; first_state = CONN_STATE_CONNECT_a;
680 C->events |= CONN_POLLOUT;
686 Conns[slot].events |= CONN_POLLOUT;
681 687 } }
682 688
683 689 ret = Conn_engine_add_obj(C); ret = Conn_engine_add_obj(C);
 
... ... int Conn_commit(struct Conn *C)
687 693 if (do_connect == 1) if (do_connect == 1)
688 694 Conn_pending++; Conn_pending++;
689 695
690 C->state = first_state;
696 Conns[slot].state = first_state;
691 697
692 698 Conn_work_to_do++; Conn_work_to_do++;
693 699
694 700 return 0; return 0;
695 701
696 702 out_free_fd: out_free_fd:
697 Conn_free_intern(C);
703 Conn_free_intern(slot);
698 704
699 705 return -1; return -1;
700 706 } }
 
... ... struct Conn *Conn_connect(const int domain, const int type, const char *addr,
768 774 return X; return X;
769 775 } }
770 776
771 static void Conn_accept(struct Conn *C)
777 static void Conn_accept(const unsigned int slot)
772 778 { {
773 779 int fd, err; int fd, err;
774 780 struct sockaddr *pca, *psa; struct sockaddr *pca, *psa;
 
... ... static void Conn_accept(struct Conn *C)
776 782 struct sockaddr_in6 ca6, sa6; struct sockaddr_in6 ca6, sa6;
777 783 socklen_t cax_len, sax_len; socklen_t cax_len, sax_len;
778 784 struct Conn *X; struct Conn *X;
779 unsigned int Cslot;
780 785
781 Log(10, "Accepting a connection via %s/%d, type %s, domain %s"
786 Log(10, "Accepting a connection on slot %u via %s/%d, type %s, domain %s"
782 787 ", protocol %s.\n", ", protocol %s.\n",
783 C->bind_addr, C->bind_port, Conn_type(C), Conn_domain(C),
784 Conn_get_socket_protocol(C));
788 slot, Conns[slot].bind_addr, Conns[slot].bind_port, Conn_type(&Conns[slot]),
789 Conn_domain(&Conns[slot]), Conn_get_socket_protocol(&Conns[slot]));
785 790
786 switch(C->sock_domain) {
791 switch(Conns[slot].sock_domain) {
787 792 case PF_INET: case PF_INET:
788 793 pca = (struct sockaddr *) &ca4; pca = (struct sockaddr *) &ca4;
789 794 cax_len = sizeof(ca4); cax_len = sizeof(ca4);
 
... ... static void Conn_accept(struct Conn *C)
801 806 default: default:
802 807 snprintf(Conn_error, sizeof(Conn_error), snprintf(Conn_error, sizeof(Conn_error),
803 808 "Cannot deal with domain %d.", "Cannot deal with domain %d.",
804 C->sock_domain);
805 Conn_error_raise(C, EAFNOSUPPORT);
809 Conns[slot].sock_domain);
810 Conn_error_raise(slot, EAFNOSUPPORT);
806 811 return; return;
807 812 } }
808 813
809 fd = accept(C->fd, pca, &cax_len);
814 fd = accept(Conns[slot].fd, pca, &cax_len);
810 815 if (fd == -1) { if (fd == -1) {
811 816 if (errno == EAGAIN) if (errno == EAGAIN)
812 817 return; return;
813 818
814 819 /* TODO: ratelimit */ /* TODO: ratelimit */
815 820 Log(9, "WARN: Cannot accept on fd %d [%s].\n", Log(9, "WARN: Cannot accept on fd %d [%s].\n",
816 C->fd, strerror(errno));
817 Conn_error_raise(C, errno);
821 Conns[slot].fd, strerror(errno));
822 Conn_error_raise(slot, errno);
818 823 return; return;
819 824 } }
820 825
821 826 /* After calling Conn_alloc, pointer to slot can change, so C is not valid */ /* After calling Conn_alloc, pointer to slot can change, so C is not valid */
822 Cslot = C->slot;
823 827 X = Conn_alloc(); X = Conn_alloc();
824 C = &Conns[Cslot];
825 828 if (!X) { if (!X) {
826 Conn_error_raise(C, ENOMEM);
829 Conn_error_raise(slot, ENOMEM);
827 830 close(fd); close(fd);
828 831 return; return;
829 832 } }
 
... ... static void Conn_accept(struct Conn *C)
832 835 X->type = CONN_TYPE_P2P; X->type = CONN_TYPE_P2P;
833 836 X->state = CONN_STATE_OPEN; X->state = CONN_STATE_OPEN;
834 837 X->time_open = Conn_now; X->time_open = Conn_now;
835 X->via = C->id;
838 X->via = Conns[slot].id;
836 839 X->events = CONN_POLLIN; X->events = CONN_POLLIN;
837 840
838 Conn_set_socket_domain(X, C->sock_domain);
839 Conn_set_socket_type(X, C->sock_type);
840 Conn_set_socket_protocol(X, C->sock_protocol);
841 Conn_set_socket_domain(X, Conns[slot].sock_domain);
842 Conn_set_socket_type(X, Conns[slot].sock_type);
843 Conn_set_socket_protocol(X, Conns[slot].sock_protocol);
841 844
842 845 Conn_setnonblock(X->fd); Conn_setnonblock(X->fd);
843 846
 
... ... static void Conn_accept(struct Conn *C)
846 849
847 850 err = Conn_engine_add_obj(X); err = Conn_engine_add_obj(X);
848 851 if (err != 0) { if (err != 0) {
849 Conn_error_raise(C, err);
850 Conn_free_intern(X);
852 Conn_error_raise(slot, err);
853 Conn_free_intern(X->slot);
851 854 return; return;
852 855 } }
853 856
854 if (C->cb_accept)
855 C->cb_accept(X);
857 if (Conns[slot].cb_accept)
858 Conns[slot].cb_accept(X);
856 859 else if (Conn_accept_cb != NULL) else if (Conn_accept_cb != NULL)
857 860 Conn_accept_cb(X); Conn_accept_cb(X);
858 861
 
... ... static void Conn_accept(struct Conn *C)
863 866
864 867 static void Conn_accept_allow(void) static void Conn_accept_allow(void)
865 868 { {
866 unsigned int i;
869 unsigned int slot;
867 870
868 871 if (Conn_accept_is_allowed == Conn_accept_is_allowed_last) if (Conn_accept_is_allowed == Conn_accept_is_allowed_last)
869 872 return; return;
 
... ... static void Conn_accept_allow(void)
872 875 __FUNCTION__, Conn_accept_is_allowed_last, __FUNCTION__, Conn_accept_is_allowed_last,
873 876 Conn_accept_is_allowed); Conn_accept_is_allowed);
874 877
875 for (i = 0; i < Conn_no; i++) {
876 if (Conns[i].type != CONN_TYPE_MASTER)
878 for (slot = 0; slot < Conn_no; slot++) {
879 if (Conns[slot].type != CONN_TYPE_MASTER)
877 880 continue; continue;
878 881
879 882 if (Conn_accept_is_allowed == 0) if (Conn_accept_is_allowed == 0)
880 Conns[i].events &= ~CONN_POLLIN;
883 Conns[slot].events &= ~CONN_POLLIN;
881 884 else else
882 Conns[i].events |= CONN_POLLIN;
885 Conns[slot].events |= CONN_POLLIN;
883 886
884 Conn_engine_chg_obj(&Conns[i]);
887 Conn_engine_chg_obj(&Conns[slot]);
885 888 } }
886 889
887 890 Conn_accept_is_allowed_last = Conn_accept_is_allowed; Conn_accept_is_allowed_last = Conn_accept_is_allowed;
 
... ... static void Conn_accept_allow(void)
890 893 /* /*
891 894 * Add tokens to connection * Add tokens to connection
892 895 */ */
893 static void Conn_band_update(struct Conn *C)
896 static void Conn_band_update(const unsigned int slot)
894 897 { {
895 898 long diff; long diff;
896 899
897 900 /* no need */ /* no need */
898 if (C->band_width == 0)
901 if (Conns[slot].band_width == 0)
899 902 return; return;
900 903
901 diff = (Conn_now.tv_sec - C->band_lasttime.tv_sec) * 1000000;
902 diff += Conn_now.tv_usec - C->band_lasttime.tv_usec;
904 diff = (Conn_now.tv_sec - Conns[slot].band_lasttime.tv_sec) * 1000000;
905 diff += Conn_now.tv_usec - Conns[slot].band_lasttime.tv_usec;
903 906 diff /= 100000; diff /= 100000;
904 907
905 908 /* already added in this hundred of milisecond? */ /* already added in this hundred of milisecond? */
 
... ... static void Conn_band_update(struct Conn *C)
910 913 if (diff < 0) if (diff < 0)
911 914 diff = 1; diff = 1;
912 915
913 C->band_lasttime = Conn_now;
914 C->band_tokens += diff * C->band_width / 10;
915 if (C->band_tokens > C->band_factor * C->band_width)
916 C->band_tokens = C->band_factor * C->band_width;
916 Conns[slot].band_lasttime = Conn_now;
917 Conns[slot].band_tokens += diff * Conns[slot].band_width / 10;
918 if (Conns[slot].band_tokens > Conns[slot].band_factor * Conns[slot].band_width)
919 Conns[slot].band_tokens = Conns[slot].band_factor * Conns[slot].band_width;
917 920
918 C->events |= CONN_POLLOUT;
919 Conn_engine_chg_obj(C);
921 Conns[slot].events |= CONN_POLLOUT;
922 Conn_engine_chg_obj(&Conns[slot]);
920 923
921 924 Log(debug_band, "\t\tBAND: slot=%u, id=%llu, added tokens -> %u.\n", Log(debug_band, "\t\tBAND: slot=%u, id=%llu, added tokens -> %u.\n",
922 C->slot, C->id, C->band_tokens);
925 slot, Conns[slot].id, Conns[slot].band_tokens);
923 926 } }
924 927
925 928 /* /*
 
... ... static void Conn_band_update(struct Conn *C)
929 932 int Conn_band(struct Conn *C, const unsigned int width, int Conn_band(struct Conn *C, const unsigned int width,
930 933 const unsigned int factor) const unsigned int factor)
931 934 { {
935 unsigned int slot;
936
937 slot = C->slot;
938
932 939 Log(11, "\tConn_band: slot=%u, id=%llu, width=%u, factor=%u.\n", Log(11, "\tConn_band: slot=%u, id=%llu, width=%u, factor=%u.\n",
933 C->slot, C->id, width, factor);
940 slot, Conns[slot].id, width, factor);
934 941
935 C->band_lasttime = Conn_now;
936 C->band_width = width;
937 C->band_factor = factor;
938 C->band_tokens = factor * width;
942 Conns[slot].band_lasttime = Conn_now;
943 Conns[slot].band_width = width;
944 Conns[slot].band_factor = factor;
945 Conns[slot].band_tokens = factor * width;
939 946
940 947 Log(debug_band, "\t\tBAND: lasttime=%d.%06d, width=%u, factor=%u, tokens=%u\n", Log(debug_band, "\t\tBAND: lasttime=%d.%06d, width=%u, factor=%u, tokens=%u\n",
941 C->band_lasttime.tv_sec, C->band_lasttime.tv_usec,
942 C->band_width, C->band_factor, C->band_tokens);
948 Conns[slot].band_lasttime.tv_sec, Conns[slot].band_lasttime.tv_usec,
949 Conns[slot].band_width, Conns[slot].band_factor, Conns[slot].band_tokens);
943 950
944 951 return 0; return 0;
945 952 } }
 
... ... static void Conn_trytoconnect(void)
1035 1042 } }
1036 1043 } }
1037 1044
1038 static void Conn_send_cb_i(struct Conn *C)
1045 static void Conn_send_cb_i(const unsigned int slot)
1039 1046 { {
1040 1047 ssize_t n; ssize_t n;
1041 1048 unsigned int max; unsigned int max;
1042 1049 int count; int count;
1043 unsigned int slot;
1044 1050 char *buf; char *buf;
1045 1051 int xerrno; int xerrno;
1046 1052 char *dump; char *dump;
1047 1053
1048 1054 Log(10, "Conn_send_cb_i slot=%u, id=%llu, head=%u, tail=%u, size=%u...\n", Log(10, "Conn_send_cb_i slot=%u, id=%llu, head=%u, tail=%u, size=%u...\n",
1049 C->slot, C->id, C->obuf_head, C->obuf_tail, C->obuf_size);
1050
1051 slot = C->slot;
1055 slot, Conns[slot].id, Conns[slot].obuf_head, Conns[slot].obuf_tail,
1056 Conns[slot].obuf_size);
1052 1057
1053 1058 if (Conns[slot].obuf == NULL) if (Conns[slot].obuf == NULL)
1054 1059 abort(); abort();
 
... ... static void Conn_send_cb_i(struct Conn *C)
1107 1112 } }
1108 1113
1109 1114 Conns[slot].bo += n; Conns[slot].bo += n;
1110 if (C->band_width > 0) {
1115 if (Conns[slot].band_width > 0) {
1111 1116 Conns[slot].band_tokens -= n; Conns[slot].band_tokens -= n;
1112 1117 Log(debug_band, "\t%s: BAND: Remove %d tokens -> %u...\n", Log(debug_band, "\t%s: BAND: Remove %d tokens -> %u...\n",
1113 1118 __FUNCTION__, __FUNCTION__,
 
... ... static void Conn_send_cb_i(struct Conn *C)
1122 1127 } }
1123 1128 } }
1124 1129
1125 static void Conn_recv_cb_i(struct Conn *C)
1130 static void Conn_recv_cb_i(const unsigned int slot)
1126 1131 { {
1127 1132 ssize_t n; ssize_t n;
1128 1133 unsigned int max; unsigned int max;
1129 unsigned int slot;
1130 1134 int r, xerrno; int r, xerrno;
1131 1135 char *dump; char *dump;
1132 1136
1133 1137 Log(10, "Conn_recv_cb_i slot=%u, id=%llu, head=%u, tail=%u, size=%u...\n", Log(10, "Conn_recv_cb_i slot=%u, id=%llu, head=%u, tail=%u, size=%u...\n",
1134 C->slot, C->id, C->ibuf_head, C->ibuf_tail, C->ibuf_size);
1135
1136 slot = C->slot;
1138 slot, Conns[slot].id, Conns[slot].ibuf_head, Conns[slot].ibuf_tail, Conns[slot].ibuf_size);
1137 1139
1138 1140 if (Conns[slot].ibuf_tail == Conns[slot].ibuf_size) { if (Conns[slot].ibuf_tail == Conns[slot].ibuf_size) {
1139 r = Conn_try_expand_buf(&Conns[slot], 1, 0);
1141 r = Conn_try_expand_buf(slot, 1, 0);
1140 1142 if (r != 0) { if (r != 0) {
1141 1143 Log(1, "MEM: Cannot expand ibuf!\n"); Log(1, "MEM: Cannot expand ibuf!\n");
1142 1144 return; return;
 
... ... static void Conn_recv_cb_i(struct Conn *C)
1162 1164
1163 1165 if (n > 0) { if (n > 0) {
1164 1166 if (Conn_level >= 10) { if (Conn_level >= 10) {
1165 dump = Conn_dump(Conns[slot].ibuf
1166 + Conns[slot].ibuf_tail, n);
1167 dump = Conn_dump(Conns[slot].ibuf + Conns[slot].ibuf_tail, n);
1167 1168 Log(0, "\t%s\n", dump); Log(0, "\t%s\n", dump);
1168 1169 free(dump); free(dump);
1169 1170 } }
 
... ... static void Conn_recv_cb_i(struct Conn *C)
1190 1191 /* /*
1191 1192 * Callback that is called for every connection * Callback that is called for every connection
1192 1193 */ */
1193 static void Conn_poll_cb(struct Conn *C, int revents)
1194 static void Conn_poll_cb(const unsigned int slot, int revents)
1194 1195 { {
1195 unsigned int slot;
1196
1197 1196 Log(12, "%s: slot=%u, id=%llu, revents=%x.\n", Log(12, "%s: slot=%u, id=%llu, revents=%x.\n",
1198 __FUNCTION__, C->slot, C->id, revents);
1199 C->revents = revents;
1197 __FUNCTION__, slot, Conns[slot].id, revents);
1198 Conns[slot].revents = revents;
1200 1199
1201 1200 if (Conn_level >= 12) if (Conn_level >= 12)
1202 Log(12, "\t%s\n", Conn_status_slot(C));
1201 Log(12, "\t%s\n", Conn_status_slot(slot));
1203 1202
1204 1203 /* We should not have events on a free cell */ /* We should not have events on a free cell */
1205 if (C->state == CONN_STATE_FREE)
1204 if (Conns[slot].state == CONN_STATE_FREE)
1206 1205 abort(); abort();
1207 1206
1208 1207 if (revents & CONN_POLLHUP) { if (revents & CONN_POLLHUP) {
1209 C->error_state = CONN_ERROR_HANGUP;
1208 Conns[slot].error_state = CONN_ERROR_HANGUP;
1210 1209 /* TODO: Add it to the close list to speed it up */ /* TODO: Add it to the close list to speed it up */
1211 1210 } }
1212 1211
1213 1212 if (revents & CONN_POLLERR) { if (revents & CONN_POLLERR) {
1214 C->error_state = CONN_ERROR_POLL;
1215 C->xerrno = 0; /* TODO: unknown error? */
1213 Conns[slot].error_state = CONN_ERROR_POLL;
1214 Conns[slot].xerrno = 0; /* TODO: unknown error? */
1216 1215 /* TODO: CONN_ERROR_POLL is correct here? */ /* TODO: CONN_ERROR_POLL is correct here? */
1217 1216 } }
1218 1217
1219 1218 /* First, test we have a new connection */ /* First, test we have a new connection */
1220 1219 if ((revents & CONN_POLLOUT) if ((revents & CONN_POLLOUT)
1221 && (Conn_ignore(C) == 0)) {
1220 && (Conn_ignore(slot) == 0)) {
1222 1221 /* We just established a connection */ /* We just established a connection */
1223 if (C->state == CONN_STATE_CONNECT_b) {
1222 if (Conns[slot].state == CONN_STATE_CONNECT_b) {
1224 1223 /* /*
1225 1224 * We do not need POLLOUT now - it was used only for * We do not need POLLOUT now - it was used only for
1226 1225 * connect completion. * connect completion.
1227 1226 */ */
1228 1227 revents &= ~CONN_POLLOUT; revents &= ~CONN_POLLOUT;
1229 C->events &= ~CONN_POLLOUT;
1230 Conn_engine_chg_obj(C);
1228 Conns[slot].events &= ~CONN_POLLOUT;
1229 Conn_engine_chg_obj(&Conns[slot]);
1231 1230
1232 C->state = CONN_STATE_OPEN;
1231 Conns[slot].state = CONN_STATE_OPEN;
1233 1232
1234 Conn_set_address(C, 0);
1233 Conn_set_address(&Conns[slot], 0);
1235 1234
1236 C->time_open = Conn_now;
1235 Conns[slot].time_open = Conn_now;
1237 1236
1238 if (C->cb_connected != NULL)
1239 C->cb_connected(C);
1237 if (Conns[slot].cb_connected != NULL)
1238 Conns[slot].cb_connected(&Conns[slot]);
1240 1239 else if (Conn_connected_cb) else if (Conn_connected_cb)
1241 Conn_connected_cb(C);
1242
1240 Conn_connected_cb(&Conns[slot]);
1243 1241 } }
1244 1242 } }
1245 1243
1246 1244 /* Second, test for error or input */ /* Second, test for error or input */
1247 1245 if ((revents & CONN_POLLIN) if ((revents & CONN_POLLIN)
1248 && (Conn_ignore(C) == 0)) {
1249 if (C->type == CONN_TYPE_MASTER) {
1246 && (Conn_ignore(slot) == 0)) {
1247 if (Conns[slot].type == CONN_TYPE_MASTER) {
1250 1248 /* C pointer can change under us in Conn_accept->Conn_grow */ /* C pointer can change under us in Conn_accept->Conn_grow */
1251 slot = C->slot;
1252 Conn_accept(C);
1253 C = &Conns[slot];
1249 Conn_accept(slot);
1254 1250 } else { } else {
1255 if (C->cb_recv)
1256 C->cb_recv(C);
1251 if (Conns[slot].cb_recv)
1252 Conns[slot].cb_recv(&Conns[slot]);
1257 1253 else if (Conn_recv_cb != NULL) else if (Conn_recv_cb != NULL)
1258 Conn_recv_cb(C);
1254 Conn_recv_cb(&Conns[slot]);
1259 1255 else else
1260 Conn_recv_cb_i(C);
1256 Conn_recv_cb_i(slot);
1261 1257 } }
1262 1258 } }
1263 1259
1264 1260 if ((revents & CONN_POLLOUT) if ((revents & CONN_POLLOUT)
1265 && (Conn_ignore(C) == 0)) {
1261 && (Conn_ignore(slot) == 0)) {
1266 1262 /* We can send data */ /* We can send data */
1267 if (C->state == CONN_STATE_OPEN) {
1268 if (C->cb_send)
1269 C->cb_send(C);
1263 if (Conns[slot].state == CONN_STATE_OPEN) {
1264 if (Conns[slot].cb_send)
1265 Conns[slot].cb_send(&Conns[slot]);
1270 1266 else if (Conn_send_cb != NULL) else if (Conn_send_cb != NULL)
1271 Conn_send_cb(C);
1267 Conn_send_cb(&Conns[slot]);
1272 1268 else else
1273 Conn_send_cb_i(C);
1274
1275 if (C->obuf_head == C->obuf_tail) {
1276 C->events &= ~CONN_POLLOUT;
1277 Conn_epoll_chg_obj(C);
1278 if (C->flags & CONN_FLAGS_CLOSE_AFTER_SEND) {
1279 C->state = CONN_STATE_ERROR;
1280 C->error_state = CONN_ERROR_USERREQ;
1269 Conn_send_cb_i(slot);
1270
1271 if (Conns[slot].obuf_head == Conns[slot].obuf_tail) {
1272 Conns[slot].events &= ~CONN_POLLOUT;
1273 Conn_epoll_chg_obj(&Conns[slot]);
1274 if (Conns[slot].flags & CONN_FLAGS_CLOSE_AFTER_SEND) {
1275 Conns[slot].state = CONN_STATE_ERROR;
1276 Conns[slot].error_state = CONN_ERROR_USERREQ;
1281 1277 } }
1282 1278 } }
1283 1279 } }
 
... ... int Conn_poll(const int timeout)
1316 1312 { {
1317 1313 int ret; int ret;
1318 1314 int timeout2; int timeout2;
1319 unsigned int i, last;
1315 unsigned int slot, last;
1320 1316
1321 1317 Log(9, "%s: timeout=%d Conn_no=%d, Conn_work_to_do=%u)\n", Log(9, "%s: timeout=%d Conn_no=%d, Conn_work_to_do=%u)\n",
1322 1318 __FUNCTION__, timeout, Conn_no, Conn_work_to_do); __FUNCTION__, timeout, Conn_no, Conn_work_to_do);
 
... ... int Conn_poll(const int timeout)
1345 1341
1346 1342 Log(9, "\tDo compacting, expiration and band stuff (%d event(s))...\n", Log(9, "\tDo compacting, expiration and band stuff (%d event(s))...\n",
1347 1343 ret); ret);
1348 i = 0;
1349 while (i < Conn_no) {
1344 slot = 0;
1345 while (slot < Conn_no) {
1350 1346 /* /*
1351 1347 * Save last position because Conn_free_intern * Save last position because Conn_free_intern
1352 1348 * decrements Conn_no * decrements Conn_no
 
... ... int Conn_poll(const int timeout)
1354 1350 last = Conn_no - 1; last = Conn_no - 1;
1355 1351
1356 1352 /* Closing connection if it is in error state */ /* Closing connection if it is in error state */
1357 if (Conns[i].error_state > 0) {
1353 if (Conns[slot].error_state > 0) {
1358 1354 Log(11, "\tSlot %u in error, exchange with pos %u.\n", Log(11, "\tSlot %u in error, exchange with pos %u.\n",
1359 i, last);
1360 Conn_move_slot(i, last);
1361 Conn_free_intern(&Conns[last]);
1355 slot, last);
1356 Conn_move_slot(slot, last);
1357 Conn_free_intern(last);
1362 1358 continue; continue;
1363 1359 } }
1364 1360
1365 1361 /* No commit done yet */ /* No commit done yet */
1366 if (Conns[i].state == CONN_STATE_EMPTY) {
1367 i++;
1362 if (Conns[slot].state == CONN_STATE_EMPTY) {
1363 slot++;
1368 1364 continue; continue;
1369 1365 } }
1370 1366
1371 if (Conns[i].state == CONN_STATE_FREE) {
1367 if (Conns[slot].state == CONN_STATE_FREE) {
1372 1368 /* Must not happen! */ /* Must not happen! */
1373 1369 abort(); abort();
1374 1370 } }
1375 1371
1376 1372 /* test if it expired/timeout */ /* test if it expired/timeout */
1377 Conn_expire(&Conns[i]);
1373 Conn_expire(slot);
1378 1374
1379 1375 /* add tokens */ /* add tokens */
1380 Conn_band_update(&Conns[i]);
1376 Conn_band_update(slot);
1381 1377
1382 i++;
1378 slot++;
1383 1379 } }
1384 1380
1385 1381 /* Blocking accept if full queue or unblock if not */ /* Blocking accept if full queue or unblock if not */
 
... ... int Conn_poll(const int timeout)
1396 1392 */ */
1397 1393 unsigned long long Conn_lifetime(struct Conn *C) unsigned long long Conn_lifetime(struct Conn *C)
1398 1394 { {
1399 return Conn_time_diff(&Conn_now, &C->time_open);
1395 unsigned int slot;
1396
1397 slot = C->slot;
1398
1399 return Conn_time_diff(&Conn_now, &Conns[slot].time_open);
1400 1400 } }
File Conn_engine_core.c changed (mode: 100644) (index f97cdfc..b166c64)
... ... char *Conn_errno(const struct Conn *C)
93 93 { {
94 94 static char buf[256]; static char buf[256];
95 95 char *is; char *is;
96 unsigned int slot;
97
98 slot = C->slot;
96 99
97 switch (C->error_state) {
100 switch (Conns[slot].error_state) {
98 101 case CONN_ERROR_USERREQ: is = "user"; break; case CONN_ERROR_USERREQ: is = "user"; break;
99 102 case CONN_ERROR_POLL: is = "poll"; break; case CONN_ERROR_POLL: is = "poll"; break;
100 103 case CONN_ERROR_RECV: is = "recv"; break; case CONN_ERROR_RECV: is = "recv"; break;
 
... ... char *Conn_errno(const struct Conn *C)
113 116 } }
114 117
115 118 snprintf(buf, sizeof(buf), "%s (%s)", snprintf(buf, sizeof(buf), "%s (%s)",
116 is, (C->xerrno > 0) ? strerror(C->xerrno) : "-");
119 is, (Conns[slot].xerrno > 0) ? strerror(Conns[slot].xerrno) : "-");
117 120
118 121 return buf; return buf;
119 122 } }
 
... ... char *Conn_errno(const struct Conn *C)
121 124 /* /*
122 125 * Raise an error. It is just a little helper. * Raise an error. It is just a little helper.
123 126 */ */
124 void Conn_error_raise(struct Conn *C, const int err)
127 void Conn_error_raise(const unsigned int slot, const int err)
125 128 { {
126 129 if (err != 0) if (err != 0)
127 C->xerrno = err;
130 Conns[slot].xerrno = err;
128 131
129 if (C->cb_error)
130 C->cb_error(C);
132 if (Conns[slot].cb_error)
133 Conns[slot].cb_error(&Conns[slot]);
131 134 else if (Conn_error_cb) else if (Conn_error_cb)
132 Conn_error_cb(C);
135 Conn_error_cb(&Conns[slot]);
133 136 } }
134 137
135 138 /* set noblocking */ /* set noblocking */
 
... ... void Conn_debug(FILE *f, const unsigned short debug)
248 251
249 252 char *Conn_state(const struct Conn *C) char *Conn_state(const struct Conn *C)
250 253 { {
251 switch (C->state) {
254 unsigned int slot;
255
256 slot = C->slot;
257
258 switch (Conns[slot].state) {
252 259 case CONN_STATE_FREE: return "FREE"; case CONN_STATE_FREE: return "FREE";
253 260 case CONN_STATE_EMPTY: return "EMPTY"; case CONN_STATE_EMPTY: return "EMPTY";
254 261 case CONN_STATE_OPEN: return "OPEN"; case CONN_STATE_OPEN: return "OPEN";
 
... ... char *Conn_state(const struct Conn *C)
266 273 * what = 0 for out buffer, what = 1 for input buffer * what = 0 for out buffer, what = 1 for input buffer
267 274 * returns 0 if OK, -1 on error * returns 0 if OK, -1 on error
268 275 */ */
269 int Conn_try_expand_buf(struct Conn *C, const int what, const unsigned int needed)
276 int Conn_try_expand_buf(const unsigned int slot, const int what, const unsigned int needed)
270 277 { {
271 278 char *p; char *p;
272 279 unsigned int hm; unsigned int hm;
273 unsigned int slot, old_size, amount, head, tail;
280 unsigned int old_size, amount, head, tail;
274 281 unsigned int default_buf, buf_size, max_buf; unsigned int default_buf, buf_size, max_buf;
275 282 char *pbuf; char *pbuf;
276 283
277 slot = C->slot;
278
279 284 if (what == 0) { if (what == 0) {
280 head = C->obuf_head;
281 tail = C->obuf_tail;
285 head = Conns[slot].obuf_head;
286 tail = Conns[slot].obuf_tail;
282 287 default_buf = Conn_default_obuf; default_buf = Conn_default_obuf;
283 288 old_size = Conns[slot].obuf_size; old_size = Conns[slot].obuf_size;
284 289 buf_size = Conns[slot].obuf_size; buf_size = Conns[slot].obuf_size;
285 290 max_buf = Conn_max_obuf; max_buf = Conn_max_obuf;
286 291 pbuf = Conns[slot].obuf; pbuf = Conns[slot].obuf;
287 292 } else { } else {
288 head = C->ibuf_head;
289 tail = C->ibuf_tail;
293 head = Conns[slot].ibuf_head;
294 tail = Conns[slot].ibuf_tail;
290 295 default_buf = Conn_default_ibuf; default_buf = Conn_default_ibuf;
291 296 old_size = Conns[slot].ibuf_size; old_size = Conns[slot].ibuf_size;
292 297 buf_size = Conns[slot].ibuf_size; buf_size = Conns[slot].ibuf_size;
 
... ... static void Conn_poll_status(const short ev, char *ret)
354 359
355 360 char *Conn_domain(const struct Conn *C) char *Conn_domain(const struct Conn *C)
356 361 { {
357 switch (C->sock_domain) {
362 unsigned int slot;
363
364 slot = C->slot;
365
366 switch (Conns[slot].sock_domain) {
358 367 case PF_INET: return "IPv4"; case PF_INET: return "IPv4";
359 368 case PF_INET6: return "IPv6"; case PF_INET6: return "IPv6";
360 369 case PF_PACKET: return "PACKET"; case PF_PACKET: return "PACKET";
 
... ... char *Conn_domain(const struct Conn *C)
365 374
366 375 char *Conn_type(const struct Conn *C) char *Conn_type(const struct Conn *C)
367 376 { {
368 switch (C->sock_type) {
377 unsigned int slot;
378
379 slot = C->slot;
380
381 switch (Conns[slot].sock_type) {
369 382 case SOCK_STREAM: return "stream"; case SOCK_STREAM: return "stream";
370 383 case SOCK_DGRAM: return "dgram"; case SOCK_DGRAM: return "dgram";
371 384 case SOCK_RAW: return "raw"; case SOCK_RAW: return "raw";
 
... ... char *Conn_type(const struct Conn *C)
376 389
377 390 char *Conn_get_socket_protocol(const struct Conn *C) char *Conn_get_socket_protocol(const struct Conn *C)
378 391 { {
379 switch (C->sock_protocol) {
392 unsigned int slot;
393
394 slot = C->slot;
395
396 switch (Conns[slot].sock_protocol) {
380 397 case IPPROTO_IP: return "IP"; case IPPROTO_IP: return "IP";
381 398
382 399 default: return "?"; default: return "?";
 
... ... char *Conn_get_socket_protocol(const struct Conn *C)
385 402
386 403 static char *Conn_socktype(const struct Conn *C) static char *Conn_socktype(const struct Conn *C)
387 404 { {
388 switch (C->type) {
405 unsigned int slot;
406
407 slot = C->slot;
408
409 switch (Conns[slot].type) {
389 410 case CONN_TYPE_UNK: return "unk"; case CONN_TYPE_UNK: return "unk";
390 411 case CONN_TYPE_MASTER: return "master"; case CONN_TYPE_MASTER: return "master";
391 412 case CONN_TYPE_P2P: return "p2p"; case CONN_TYPE_P2P: return "p2p";
 
... ... void Conn_speed(char *dst, const unsigned int dst_len, const unsigned int speed)
410 431 snprintf(dst, dst_len, "%.2fMBps", sp / 1000 / 1000); snprintf(dst, dst_len, "%.2fMBps", sp / 1000 / 1000);
411 432 } }
412 433
413 char *Conn_status_slot(struct Conn *C)
434 char *Conn_status_slot(const unsigned int slot)
414 435 { {
415 436 static char tmp[1024]; static char tmp[1024];
416 437 char polle[16], pollr[16]; char polle[16], pollr[16];
 
... ... char *Conn_status_slot(struct Conn *C)
426 447 strcpy(flags_prefix, " ["); strcpy(flags_prefix, " [");
427 448 strcpy(flags_postfix, ""); strcpy(flags_postfix, "");
428 449
429 if (C->flags & CONN_FLAGS_AUTO_RECONNECT) {
450 if (Conns[slot].flags & CONN_FLAGS_AUTO_RECONNECT) {
430 451 strcat(flags, flags_prefix); strcat(flags, flags_prefix);
431 452 snprintf(flags_tmp, sizeof(flags_tmp), "autoreconnect_in_%ld/%u", snprintf(flags_tmp, sizeof(flags_tmp), "autoreconnect_in_%ld/%u",
432 (C->tryat == 0) ? 0 : C->tryat - Conn_now.tv_sec,
433 C->delay);
453 (Conns[slot].tryat == 0) ? 0 : Conns[slot].tryat - Conn_now.tv_sec,
454 Conns[slot].delay);
434 455 strcat(flags, flags_tmp); strcat(flags, flags_tmp);
435 456 strcpy(flags_prefix, " "); strcpy(flags_prefix, " ");
436 457 strcpy(flags_postfix, "]"); strcpy(flags_postfix, "]");
437 458 } }
438 if (C->flags & CONN_FLAGS_CLOSE_AFTER_SEND) {
459 if (Conns[slot].flags & CONN_FLAGS_CLOSE_AFTER_SEND) {
439 460 strcat(flags, flags_prefix); strcat(flags, flags_prefix);
440 461 strcat(flags, "close_after_send"); strcat(flags, "close_after_send");
441 462 strcpy(flags_prefix, " "); strcpy(flags_prefix, " ");
 
... ... char *Conn_status_slot(struct Conn *C)
444 465
445 466 strcat(flags, flags_postfix); strcat(flags, flags_postfix);
446 467
447 Conn_poll_status(C->events, polle);
448 Conn_poll_status(C->revents, pollr);
468 Conn_poll_status(Conns[slot].events, polle);
469 Conn_poll_status(Conns[slot].revents, pollr);
449 470
450 dT = Conn_now.tv_sec - C->start;
471 dT = Conn_now.tv_sec - Conns[slot].start;
451 472 if (dT == 0) if (dT == 0)
452 473 dT = 1; dT = 1;
453 si = C->bi / dT;
454 so = C->bo / dT;
474 si = Conns[slot].bi / dT;
475 so = Conns[slot].bo / dT;
455 476
456 477 Conn_speed(speedi, sizeof(speedi), si); Conn_speed(speedi, sizeof(speedi), si);
457 478 Conn_speed(speedo, sizeof(speedo), so); Conn_speed(speedo, sizeof(speedo), so);
 
... ... char *Conn_status_slot(struct Conn *C)
460 481 local_port = 0; local_port = 0;
461 482 remote_addr = "-"; remote_addr = "-";
462 483 remote_port = 0; remote_port = 0;
463 if (C->type == CONN_TYPE_MASTER) {
464 local_addr = C->bind_addr;
465 local_port = C->bind_port;
466 } else if (C->type == CONN_TYPE_P2P) {
467 if (strlen(C->bind_addr) > 0) {
468 local_addr = C->bind_addr;
469 local_port = C->bind_port;
484 if (Conns[slot].type == CONN_TYPE_MASTER) {
485 local_addr = Conns[slot].bind_addr;
486 local_port = Conns[slot].bind_port;
487 } else if (Conns[slot].type == CONN_TYPE_P2P) {
488 if (strlen(Conns[slot].bind_addr) > 0) {
489 local_addr = Conns[slot].bind_addr;
490 local_port = Conns[slot].bind_port;
470 491 } }
471 remote_addr = C->addr;
472 remote_port = C->port;
492 remote_addr = Conns[slot].addr;
493 remote_port = Conns[slot].port;
473 494 } }
474 495
475 496 snprintf(tmp, sizeof(tmp), "id=%llu slot=%d fd=%d" snprintf(tmp, sizeof(tmp), "id=%llu slot=%d fd=%d"
 
... ... char *Conn_status_slot(struct Conn *C)
480 501 " BS=%u/%u S=%s/%s" " BS=%u/%u S=%s/%s"
481 502 " T=%ld bw=%u f=%u tk=%u" " T=%ld bw=%u f=%u tk=%u"
482 503 "%s\n", "%s\n",
483 C->id, C->slot, C->fd,
484 Conn_domain(C), Conn_type(C), Conn_get_socket_protocol(C),
485 Conn_socktype(C), Conn_state(C),
504 Conns[slot].id, slot, Conns[slot].fd,
505 Conn_domain(&Conns[slot]), Conn_type(&Conns[slot]),
506 Conn_get_socket_protocol(&Conns[slot]),
507 Conn_socktype(&Conns[slot]), Conn_state(&Conns[slot]),
486 508 local_addr, local_port, remote_addr, remote_port, local_addr, local_port, remote_addr, remote_port,
487 C->via, polle, pollr, C->bi, C->bo,
488 C->ibuf_size, C->obuf_size, speedi, speedo,
489 Conn_now.tv_sec - C->start,
490 C->band_width, C->band_factor, C->band_tokens,
509 Conns[slot].via, polle, pollr, Conns[slot].bi, Conns[slot].bo,
510 Conns[slot].ibuf_size, Conns[slot].obuf_size, speedi, speedo,
511 Conn_now.tv_sec - Conns[slot].start,
512 Conns[slot].band_width, Conns[slot].band_factor, Conns[slot].band_tokens,
491 513 flags); flags);
492 514
493 515 return tmp; return tmp;
494 516 } }
495 517
496 char *Conn_status_slot_html(const struct Conn *C)
518 char *Conn_status_slot_html(const unsigned int slot)
497 519 { {
498 520 static char tmp[1024]; static char tmp[1024];
499 521 char polle[16], pollr[16], *ext = ""; char polle[16], pollr[16], *ext = "";
500 522 char speedi[32], speedo[32]; char speedi[32], speedo[32];
501 523 unsigned int dT, si, so; unsigned int dT, si, so;
502 524
503 Conn_poll_status(C->events, polle);
504 Conn_poll_status(C->revents, pollr);
525 Conn_poll_status(Conns[slot].events, polle);
526 Conn_poll_status(Conns[slot].revents, pollr);
505 527
506 dT = Conn_now.tv_sec - C->start;
528 dT = Conn_now.tv_sec - Conns[slot].start;
507 529 if (dT == 0) if (dT == 0)
508 530 dT = 1; dT = 1;
509 si = C->bi / dT;
510 so = C->bo / dT;
531 si = Conns[slot].bi / dT;
532 so = Conns[slot].bo / dT;
511 533
512 534 Conn_speed(speedi, sizeof(speedi), si); Conn_speed(speedi, sizeof(speedi), si);
513 535 Conn_speed(speedo, sizeof(speedo), so); Conn_speed(speedo, sizeof(speedo), so);
514 536
515 537 if (Conn_status_slot_html_cb) if (Conn_status_slot_html_cb)
516 ext = Conn_status_slot_html_cb(C);
538 ext = Conn_status_slot_html_cb(&Conns[slot]);
517 539
518 540 snprintf(tmp, sizeof(tmp), "<td>%llu</td><td>%d</td><td>%d</td>" snprintf(tmp, sizeof(tmp), "<td>%llu</td><td>%d</td><td>%d</td>"
519 541 "<td>%s</td><td>%s</td><td>%s</td>" "<td>%s</td><td>%s</td><td>%s</td>"
 
... ... char *Conn_status_slot_html(const struct Conn *C)
523 545 "<td>%u / %u</td><td>%s / %s</td><td>%ld</td>" "<td>%u / %u</td><td>%s / %s</td><td>%ld</td>"
524 546 "<td>%u</td><td>%u</td><td>%u</td>" "<td>%u</td><td>%u</td><td>%u</td>"
525 547 "%s\n", "%s\n",
526 C->id, C->slot, C->fd,
527 Conn_domain(C), Conn_type(C), Conn_get_socket_protocol(C),
528 Conn_socktype(C), Conn_state(C),
529 C->addr, C->port, C->via, polle, pollr, C->bi, C->bo,
530 C->ibuf_size, C->obuf_size,
531 speedi, speedo, Conn_now.tv_sec - C->start,
532 C->band_width, C->band_factor, C->band_tokens,
548 Conns[slot].id, slot, Conns[slot].fd,
549 Conn_domain(&Conns[slot]), Conn_type(&Conns[slot]),
550 Conn_get_socket_protocol(&Conns[slot]),
551 Conn_socktype(&Conns[slot]), Conn_state(&Conns[slot]),
552 Conns[slot].addr, Conns[slot].port, Conns[slot].via, polle, pollr, Conns[slot].bi, Conns[slot].bo,
553 Conns[slot].ibuf_size, Conns[slot].obuf_size,
554 speedi, speedo, Conn_now.tv_sec - Conns[slot].start,
555 Conns[slot].band_width, Conns[slot].band_factor, Conns[slot].band_tokens,
533 556 ext); ext);
534 557
535 558 return tmp; return tmp;
 
... ... char *Conn_status_slot_html(const struct Conn *C)
538 561 /* flags: bit 1 = 1 - html */ /* flags: bit 1 = 1 - html */
539 562 char *Conn_status(const unsigned int flags) char *Conn_status(const unsigned int flags)
540 563 { {
541 unsigned int len = 0, i, max;
542 struct Conn *C;
564 unsigned int len = 0, slot, max;
543 565 char tmp[512], tmp_len; char tmp[512], tmp_len;
544 566 char polle[16], pollr[16]; char polle[16], pollr[16];
545 char *buf, *slot, *ext = "";
567 char *buf, *per_slot, *ext = "";
546 568 char speedi[32], speedo[32]; char speedi[32], speedo[32];
547 569 unsigned long long bi, bo, dT; unsigned long long bi, bo, dT;
548 570
 
... ... char *Conn_status(const unsigned int flags)
598 620 } }
599 621
600 622 bi = 0; bo = 0; dT = 0; bi = 0; bo = 0; dT = 0;
601 for (i = 0; i < Conn_no; i++) {
602 C = &Conns[i];
603 if (C->state == CONN_STATE_FREE)
623 for (slot = 0; slot < Conn_no; slot++) {
624 if (Conns[slot].state == CONN_STATE_FREE)
604 625 continue; continue;
605 626
606 if (C->type == CONN_TYPE_P2P) {
607 bi += C->bi;
608 bo += C->bo;
609 dT += Conn_now.tv_sec - C->start;
627 if (Conns[slot].type == CONN_TYPE_P2P) {
628 bi += Conns[slot].bi;
629 bo += Conns[slot].bo;
630 dT += Conn_now.tv_sec - Conns[slot].start;
610 631 } }
611 632
612 633 if (flags & 1) if (flags & 1)
613 634 strcat(buf, "<tr bgcolor=\"ffffff\">\n"); strcat(buf, "<tr bgcolor=\"ffffff\">\n");
614 635
615 Conn_poll_status(C->events, polle);
616 Conn_poll_status(C->revents, pollr);
636 Conn_poll_status(Conns[slot].events, polle);
637 Conn_poll_status(Conns[slot].revents, pollr);
617 638
618 639 if ((flags & 1) == 0) if ((flags & 1) == 0)
619 slot = Conn_status_slot(C);
640 per_slot = Conn_status_slot(slot);
620 641 else else
621 slot = Conn_status_slot_html(C);
622 len += snprintf(tmp, sizeof(tmp), "%s", slot);
642 per_slot = Conn_status_slot_html(slot);
643 len += snprintf(tmp, sizeof(tmp), "%s", per_slot);
623 644 if (len < max) if (len < max)
624 645 strcat(buf, tmp); strcat(buf, tmp);
625 646
 
... ... char *Conn_status(const unsigned int flags)
652 673 */ */
653 674 unsigned int Conn_qlen(const struct Conn *C) unsigned int Conn_qlen(const struct Conn *C)
654 675 { {
655 return C->ibuf_tail - C->ibuf_head;
676 unsigned int slot;
677
678 slot = C->slot;
679
680 return Conns[slot].ibuf_tail - Conns[slot].ibuf_head;
656 681 } }
657 682
658 683 /* /*
659 684 * Returns 1 if we can ignore this connection * Returns 1 if we can ignore this connection
660 685 */ */
661 int Conn_ignore(const struct Conn *C)
686 int Conn_ignore(const unsigned int slot)
662 687 { {
663 if (C->error_state > 0)
688 if (Conns[slot].error_state > 0)
664 689 return 1; return 1;
665 690
666 691 return 0; return 0;
 
... ... int Conn_ignore(const struct Conn *C)
669 694 /* /*
670 695 * Close a connection if it exceeded maximum idle time or got a timeout * Close a connection if it exceeded maximum idle time or got a timeout
671 696 */ */
672 void Conn_expire(struct Conn *C)
697 void Conn_expire(const unsigned int slot)
673 698 { {
674 699 long long diff_ms; long long diff_ms;
675 700
676 if (C->trigger > 0) {
701 if (Conns[slot].trigger > 0) {
677 702 /* We do not trigger first time */ /* We do not trigger first time */
678 if (C->last_trigger == 0)
679 C->last_trigger = Conn_now.tv_sec;
703 if (Conns[slot].last_trigger == 0)
704 Conns[slot].last_trigger = Conn_now.tv_sec;
680 705
681 if ((C->last_trigger > 0)
682 && (C->last_trigger + C->trigger < Conn_now.tv_sec)) {
683 if (C->cb_trigger)
684 C->cb_trigger(C);
706 if ((Conns[slot].last_trigger > 0)
707 && (Conns[slot].last_trigger + Conns[slot].trigger < Conn_now.tv_sec)) {
708 if (Conns[slot].cb_trigger)
709 Conns[slot].cb_trigger(&Conns[slot]);
685 710 else if (Conn_trigger_cb) else if (Conn_trigger_cb)
686 Conn_trigger_cb(C);
687 C->last_trigger = C->last_trigger + C->trigger;
711 Conn_trigger_cb(&Conns[slot]);
712 Conns[slot].last_trigger = Conns[slot].last_trigger + Conns[slot].trigger;
688 713 } }
689 714 } }
690 715
691 if ((C->idle > 0) && (C->trecv.tv_sec + C->idle < Conn_now.tv_sec)) {
692 C->error_state = CONN_ERROR_EXPIRED;
693 } else if ((C->read_timeout > 0) && (C->tsend.tv_sec > 0)
694 && (C->tsend.tv_sec > C->trecv.tv_sec)) {
695 diff_ms = Conn_time_diff(&Conn_now, &C->tsend);
696 if (diff_ms > C->read_timeout) {
697 C->error_state = CONN_ERROR_READ_TIMEOUT;
716 if ((Conns[slot].idle > 0) && (Conns[slot].trecv.tv_sec + Conns[slot].idle < Conn_now.tv_sec)) {
717 Conns[slot].error_state = CONN_ERROR_EXPIRED;
718 } else if ((Conns[slot].read_timeout > 0) && (Conns[slot].tsend.tv_sec > 0)
719 && (Conns[slot].tsend.tv_sec > Conns[slot].trecv.tv_sec)) {
720 diff_ms = Conn_time_diff(&Conn_now, &Conns[slot].tsend);
721 if (diff_ms > Conns[slot].read_timeout) {
722 Conns[slot].error_state = CONN_ERROR_READ_TIMEOUT;
698 723 } }
699 } else if ((C->conn_timeout > 0) && (C->state == CONN_STATE_CONNECT_b)) {
700 diff_ms = Conn_time_diff(&Conn_now, &C->conn_syn);
701 if (diff_ms > C->conn_timeout) {
724 } else if ((Conns[slot].conn_timeout > 0) && (Conns[slot].state == CONN_STATE_CONNECT_b)) {
725 diff_ms = Conn_time_diff(&Conn_now, &Conns[slot].conn_syn);
726 if (diff_ms > Conns[slot].conn_timeout) {
702 727 /* connection attempt expired */ /* connection attempt expired */
703 C->error_state = CONN_ERROR_CONN_TIMEOUT;
728 Conns[slot].error_state = CONN_ERROR_CONN_TIMEOUT;
704 729 } }
705 730 } }
706 731 } }
 
... ... void Conn_expire(struct Conn *C)
711 736 int Conn_nodelay(const struct Conn *C) int Conn_nodelay(const struct Conn *C)
712 737 { {
713 738 int i = 1; int i = 1;
739 unsigned int slot;
714 740
715 return setsockopt(C->fd, SOL_TCP, TCP_NODELAY, &i, sizeof(i));
741 slot = C->slot;
742
743 return setsockopt(Conns[slot].fd, SOL_TCP, TCP_NODELAY, &i, sizeof(i));
716 744 } }
717 745
718 746 void Conn_rollback(struct Conn *C, const unsigned int bytes) void Conn_rollback(struct Conn *C, const unsigned int bytes)
719 747 { {
720 if (C->obuf_tail - C->obuf_head <= bytes)
721 C->obuf_tail -= bytes;
748 unsigned int slot;
749
750 slot = C->slot;
751
752 if (Conns[slot].obuf_tail - Conns[slot].obuf_head <= bytes)
753 Conns[slot].obuf_tail -= bytes;
722 754 } }
723 755
724 756 /* /*
 
... ... void Conn_rollback(struct Conn *C, const unsigned int bytes)
726 758 */ */
727 759 char *Conn_ibuf(const struct Conn *C) char *Conn_ibuf(const struct Conn *C)
728 760 { {
729 return C->ibuf + C->ibuf_head;
761 unsigned int slot;
762
763 slot = C->slot;
764
765 return Conns[slot].ibuf + Conns[slot].ibuf_head;
730 766 } }
731 767
732 768 /* /*
 
... ... char *Conn_ibuf(const struct Conn *C)
734 770 */ */
735 771 char *Conn_obuf(const struct Conn *C) char *Conn_obuf(const struct Conn *C)
736 772 { {
737 return C->obuf + C->obuf_head;
773 unsigned int slot;
774
775 slot = C->slot;
776
777 return Conns[slot].obuf + Conns[slot].obuf_head;
738 778 } }
739 779
740 780 /* /*
 
... ... char *Conn_obuf(const struct Conn *C)
742 782 */ */
743 783 unsigned long long Conn_getid(const struct Conn *C) unsigned long long Conn_getid(const struct Conn *C)
744 784 { {
745 return C->id;
785 unsigned int slot;
786
787 slot = C->slot;
788
789 return Conns[slot].id;
746 790 } }
747 791
748 792 /* /*
 
... ... struct Conn *Conn_get(const unsigned long long id)
768 812 */ */
769 813 int Conn_get_fd(const struct Conn *C) int Conn_get_fd(const struct Conn *C)
770 814 { {
771 if (C == NULL)
772 return -1;
815 unsigned int slot;
773 816
774 return C->fd;
817 slot = C->slot;
818
819 return Conns[slot].fd;
775 820 } }
776 821
777 822 /* /*
 
... ... int Conn_get_fd(const struct Conn *C)
779 824 */ */
780 825 void Conn_last_time(const struct Conn *C, struct timeval *tv) void Conn_last_time(const struct Conn *C, struct timeval *tv)
781 826 { {
782 *tv = C->trecv;
827 unsigned int slot;
828
829 slot = C->slot;
830
831 *tv = Conns[slot].trecv;
832 }
833
834 /*
835 * Set a callback
836 */
837 int Conn_set_cb(struct Conn *C, const unsigned int cb_type, void (*f)(struct Conn *))
838 {
839 unsigned int slot;
840
841 slot = C->slot;
842
843 switch (cb_type) {
844 case CONN_CB_ACCEPT: Conns[slot].cb_accept = f; break;
845 case CONN_CB_RECV: Conns[slot].cb_recv = f; break;
846 case CONN_CB_SEND: Conns[slot].cb_send = f; break;
847 case CONN_CB_DATA: Conns[slot].cb_data = f; break;
848 case CONN_CB_CLOSE: Conns[slot].cb_close = f; break;
849 case CONN_CB_TRIGGER: Conns[slot].cb_trigger = f; break;
850 case CONN_CB_ERROR: Conns[slot].cb_error = f; break;
851 case CONN_CB_CONNECTED: Conns[slot].cb_connected = f; break;
852 case CONN_CB_ACCEPT_ERROR: Conns[slot].cb_accept_error = f; break;
853
854 default:
855 return -1;
856 }
857
858 return 0;
783 859 } }
784 860
785 861 /* /*
 
... ... char *Conn_ostrstr(struct Conn *C, const unsigned int off, const char *str,
793 869 unsigned int len, str_len, i; unsigned int len, str_len, i;
794 870 char *buf, *ret = NULL; char *buf, *ret = NULL;
795 871 int err; int err;
872 unsigned int slot;
796 873
797 len = C->ibuf_tail - C->ibuf_head - off;
798 buf = C->ibuf + C->ibuf_head + off;
874 slot = C->slot;
875
876 len = Conns[slot].ibuf_tail - Conns[slot].ibuf_head - off;
877 buf = Conns[slot].ibuf + Conns[slot].ibuf_head + off;
799 878 str_len = strlen(str); str_len = strlen(str);
800 879
801 880 if (len < str_len) if (len < str_len)
 
... ... char *Conn_strcasestr(struct Conn *C, const char *str)
836 915 return Conn_ostrstr(C, 0, str, 1); return Conn_ostrstr(C, 0, str, 1);
837 916 } }
838 917
839 /*
840 * Set a callback
841 */
842 int Conn_set_cb(struct Conn *C, const unsigned int type, void (*f)(struct Conn *))
843 {
844 switch (type) {
845 case CONN_CB_ACCEPT: C->cb_accept = f; break;
846 case CONN_CB_RECV: C->cb_recv = f; break;
847 case CONN_CB_SEND: C->cb_send = f; break;
848 case CONN_CB_DATA: C->cb_data = f; break;
849 case CONN_CB_CLOSE: C->cb_close = f; break;
850 case CONN_CB_TRIGGER: C->cb_trigger = f; break;
851 case CONN_CB_ERROR: C->cb_error = f; break;
852 case CONN_CB_CONNECTED: C->cb_connected = f; break;
853 case CONN_CB_ACCEPT_ERROR: C->cb_accept_error = f; break;
854
855 default:
856 return -1;
857 }
858
859 return 0;
860 }
861
862 918 /* /*
863 919 * Returns a '\0' terminated line, modifying received buffer * Returns a '\0' terminated line, modifying received buffer
864 920 */ */
 
... ... void Conn_for_every_line(struct Conn *C, int (*cb)(struct Conn *C, char *line))
883 939 int ret = 0; int ret = 0;
884 940 char *line; char *line;
885 941 unsigned int line_size; unsigned int line_size;
942 unsigned int slot;
943
944 slot = C->slot;
886 945
887 946 if (cb == NULL) if (cb == NULL)
888 947 return; return;
889 948
890 949 while (1) { while (1) {
891 line = Conn_get_line(C);
950 line = Conn_get_line(&Conns[slot]);
892 951 if (line == NULL) if (line == NULL)
893 952 break; break;
894 953
 
... ... void Conn_for_every_line(struct Conn *C, int (*cb)(struct Conn *C, char *line))
896 955
897 956 Conn_rtrim(line, "\r"); Conn_rtrim(line, "\r");
898 957
899 ret = cb(C, line);
958 ret = cb(&Conns[slot], line);
900 959 if (ret != 0) if (ret != 0)
901 960 break; break;
902 961
903 Conn_eat(C, line_size);
962 Conn_eat(&Conns[slot], line_size);
904 963 } }
905 964 } }
906 965
 
... ... void Conn_eat(struct Conn *C, const unsigned int bytes)
921 980 } }
922 981
923 982 Log(10, "Conn_eat(C, %u) head=%u tail=%u qlen=%u\n", Log(10, "Conn_eat(C, %u) head=%u tail=%u qlen=%u\n",
924 bytes, C->ibuf_head, C->ibuf_tail,
925 Conn_qlen(C));
983 bytes, Conns[slot].ibuf_head, Conns[slot].ibuf_tail,
984 Conn_qlen(&Conns[slot]));
926 985 } }
927 986
928 987 /* /*
 
... ... void Conn_eatall(struct Conn *C)
939 998 */ */
940 999 void Conn_close(struct Conn *C) void Conn_close(struct Conn *C)
941 1000 { {
1001 unsigned int slot;
1002
1003 slot = C->slot;
1004
942 1005 Log(10, "%s: Mark slot=%u, id=%llu for closing...\n", Log(10, "%s: Mark slot=%u, id=%llu for closing...\n",
943 __FUNCTION__, C->slot, C->id);
1006 __FUNCTION__, slot, Conns[slot].id);
944 1007
945 if (C->obuf_head == C->obuf_tail)
946 C->error_state = CONN_ERROR_USERREQ;
1008 if (Conns[slot].obuf_head == Conns[slot].obuf_tail)
1009 Conns[slot].error_state = CONN_ERROR_USERREQ;
947 1010 else else
948 C->flags |= CONN_FLAGS_CLOSE_AFTER_SEND;
1011 Conns[slot].flags |= CONN_FLAGS_CLOSE_AFTER_SEND;
949 1012 } }
950 1013
951 1014 /* /*
 
... ... void Conn_stop(void)
962 1025 void Conn_set(struct Conn *C, const unsigned int var, const int val) void Conn_set(struct Conn *C, const unsigned int var, const int val)
963 1026 { {
964 1027 int fd; int fd;
1028 unsigned int slot;
1029
1030 slot = C->slot;
965 1031
966 1032 fd = Conn_get_fd(C); fd = Conn_get_fd(C);
967 1033
968 1034 switch (var) { switch (var) {
969 1035 case CONN_PARA_AUTO_RECONNECT: case CONN_PARA_AUTO_RECONNECT:
970 C->flags |= (val == 0) ? 0 : CONN_FLAGS_AUTO_RECONNECT;
1036 Conns[slot].flags |= (val == 0) ? 0 : CONN_FLAGS_AUTO_RECONNECT;
971 1037 break; break;
972 1038 case CONN_PARA_RECONNECT_DELAY: case CONN_PARA_RECONNECT_DELAY:
973 C->delay = val;
1039 Conns[slot].delay = val;
974 1040 break; break;
975 1041 case CONN_PARA_IDLE_TIME: case CONN_PARA_IDLE_TIME:
976 C->idle = val;
1042 Conns[slot].idle = val;
977 1043 break; break;
978 1044 case CONN_PARA_READ_TIMEOUT: case CONN_PARA_READ_TIMEOUT:
979 C->read_timeout = val;
1045 Conns[slot].read_timeout = val;
980 1046 break; break;
981 1047 case CONN_PARA_CONN_TIMEOUT: case CONN_PARA_CONN_TIMEOUT:
982 C->conn_timeout = val;
1048 Conns[slot].conn_timeout = val;
983 1049 break; break;
984 1050 case CONN_PARA_TRIGGER: case CONN_PARA_TRIGGER:
985 C->trigger = val;
986 C->last_trigger = 0;
1051 Conns[slot].trigger = val;
1052 Conns[slot].last_trigger = 0;
987 1053 break; break;
988 1054 case CONN_PARA_IBUF: case CONN_PARA_IBUF:
989 1055 setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
 
... ... int Conn_set_address(struct Conn *C, const int flags)
1059 1125 char *paddr; char *paddr;
1060 1126 size_t addr_size; size_t addr_size;
1061 1127 int *pport; int *pport;
1128 unsigned int slot;
1062 1129
1063 switch (C->sock_domain) {
1130 slot = C->slot;
1131
1132 switch (Conns[slot].sock_domain) {
1064 1133 case PF_INET: case PF_INET:
1065 1134 psa = (struct sockaddr *) &sa4; psa = (struct sockaddr *) &sa4;
1066 1135 sa_len = sizeof(struct sockaddr_in); sa_len = sizeof(struct sockaddr_in);
 
... ... int Conn_set_address(struct Conn *C, const int flags)
1075 1144
1076 1145 if (flags & 1) { if (flags & 1) {
1077 1146 /* peer */ /* peer */
1078 paddr = C->addr;
1079 addr_size = sizeof(C->addr);
1080 pport = &C->port;
1081 err = getpeername(C->fd, psa, &sa_len);
1147 paddr = Conns[slot].addr;
1148 addr_size = sizeof(Conns[slot].addr);
1149 pport = &Conns[slot].port;
1150 err = getpeername(Conns[slot].fd, psa, &sa_len);
1082 1151 } else { } else {
1083 1152 /* local */ /* local */
1084 paddr = C->bind_addr;
1085 addr_size = sizeof(C->bind_addr);
1086 pport = &C->bind_port;
1087 err = getsockname(C->fd, psa, &sa_len);
1153 paddr = Conns[slot].bind_addr;
1154 addr_size = sizeof(Conns[slot].bind_addr);
1155 pport = &Conns[slot].bind_port;
1156 err = getsockname(Conns[slot].fd, psa, &sa_len);
1088 1157 } }
1089 1158
1090 1159 if (err != 0) if (err != 0)
1091 1160 return -1; return -1;
1092 1161
1093 switch (C->sock_domain) {
1162 switch (Conns[slot].sock_domain) {
1094 1163 case PF_INET: case PF_INET:
1095 inet_ntop(C->sock_domain, &sa4.sin_addr,
1164 inet_ntop(Conns[slot].sock_domain, &sa4.sin_addr,
1096 1165 paddr, addr_size); paddr, addr_size);
1097 1166 *pport = ntohs(sa4.sin_port); *pport = ntohs(sa4.sin_port);
1098 1167 break; break;
1099 1168 case PF_INET6: case PF_INET6:
1100 inet_ntop(C->sock_domain, &sa6.sin6_addr,
1169 inet_ntop(Conns[slot].sock_domain, &sa6.sin6_addr,
1101 1170 paddr, addr_size); paddr, addr_size);
1102 1171 *pport = ntohs(sa6.sin6_port); *pport = ntohs(sa6.sin6_port);
1103 1172 break; break;
 
... ... int Conn_alphanum(const char *s)
1397 1466
1398 1467 return 1; return 1;
1399 1468 } }
1400
File Conn_engine_core.h changed (mode: 100644) (index 79781cb..f975897)
28 28
29 29
30 30 /* type */ /* type */
31 enum {
31 enum CONN_TYPE {
32 32 CONN_TYPE_UNK = 0, CONN_TYPE_UNK = 0,
33 33 CONN_TYPE_MASTER, CONN_TYPE_MASTER,
34 34 CONN_TYPE_P2P CONN_TYPE_P2P
35 35 }; };
36 36
37 37 /* state */ /* state */
38 enum {
38 enum CONN_STATE {
39 39 CONN_STATE_FREE = 0, CONN_STATE_FREE = 0,
40 40 CONN_STATE_EMPTY, CONN_STATE_EMPTY,
41 41 CONN_STATE_OPEN, CONN_STATE_OPEN,
 
... ... enum {
47 47 }; };
48 48
49 49 /* error kind */ /* error kind */
50 enum {
50 enum CONN_ERROR {
51 51 CONN_ERROR_NO_ERROR = 0, CONN_ERROR_NO_ERROR = 0,
52 52 CONN_ERROR_USERREQ, /* user requested the close */ CONN_ERROR_USERREQ, /* user requested the close */
53 53 CONN_ERROR_POLL, CONN_ERROR_POLL,
 
... ... enum {
70 70 #define CONN_FLAGS_CLOSE_AFTER_SEND 0x01 << 1 #define CONN_FLAGS_CLOSE_AFTER_SEND 0x01 << 1
71 71
72 72 /* Parameters */ /* Parameters */
73 enum {
73 enum CONN_PARA {
74 74 CONN_PARA_AUTO_RECONNECT = 0, CONN_PARA_AUTO_RECONNECT = 0,
75 75 CONN_PARA_RECONNECT_DELAY, CONN_PARA_RECONNECT_DELAY,
76 76 CONN_PARA_IDLE_TIME, CONN_PARA_IDLE_TIME,
 
... ... enum {
82 82 }; };
83 83
84 84 /* Callbacks */ /* Callbacks */
85 enum {
85 enum CONN_CB {
86 86 CONN_CB_ACCEPT = 0, CONN_CB_ACCEPT = 0,
87 87 CONN_CB_RECV, CONN_CB_RECV,
88 88 CONN_CB_SEND, CONN_CB_SEND,
 
... ... enum {
95 95 }; };
96 96
97 97 /* Engine type */ /* Engine type */
98 enum {
98 enum CONN_ENGINE {
99 99 CONN_ENGINE_POLL = 1, CONN_ENGINE_POLL = 1,
100 100 CONN_ENGINE_EPOLL CONN_ENGINE_EPOLL
101 101 }; };
 
... ... extern struct Conn_queue Conn_queue_free;
262 262 extern char *Conn_strerror(void); extern char *Conn_strerror(void);
263 263 extern void Log(const unsigned short level, char *format, ...); extern void Log(const unsigned short level, char *format, ...);
264 264 extern char *Conn_errno(const struct Conn *C); extern char *Conn_errno(const struct Conn *C);
265 extern char *Conn_status_slot(struct Conn *C);
265 extern char *Conn_status_slot(const unsigned int slot);
266 266 extern char *Conn_status(const unsigned int flags); extern char *Conn_status(const unsigned int flags);
267 extern int Conn_try_expand_buf(struct Conn *C, const int what,
267 extern int Conn_try_expand_buf(const unsigned int slot, const int what,
268 268 const unsigned int needed); const unsigned int needed);
269 269 extern char *Conn_state(const struct Conn *C); extern char *Conn_state(const struct Conn *C);
270 270
 
... ... extern void Conn_debug(FILE *f, const unsigned short debug);
280 280
281 281 extern void Conn_close(struct Conn *C); extern void Conn_close(struct Conn *C);
282 282
283 extern int Conn_ignore(const struct Conn *C);
283 extern int Conn_ignore(const unsigned int slot);
284 284
285 extern void Conn_expire(struct Conn *C);
285 extern void Conn_expire(const unsigned int slot);
286 286
287 extern int Conn_set_cb(struct Conn *C, const unsigned int type,
287 extern int Conn_set_cb(struct Conn *C, const unsigned int cb_type,
288 288 void (*f)(struct Conn *)); void (*f)(struct Conn *));
289 289 extern char *Conn_get_line(struct Conn *C); extern char *Conn_get_line(struct Conn *C);
290 290 extern void Conn_for_every_line(struct Conn *C, extern void Conn_for_every_line(struct Conn *C,
 
... ... extern char *Conn_get_socket_protocol(const struct Conn *C);
313 313
314 314 extern int Conn_addr_family(const char *addr); extern int Conn_addr_family(const char *addr);
315 315
316 extern void Conn_error_raise(struct Conn *C, const int err);
316 extern void Conn_error_raise(const unsigned int slot, const int err);
317 317
318 318 extern void Conn_stop(void); extern void Conn_stop(void);
319 319
File Conn_engine_epoll.c changed (mode: 100644) (index bbcd956..3f6bac3)
... ... int Conn_epoll_chg_obj(struct Conn *C)
144 144 * Returns: -1 on error, 0 nothing to do, n (>0) if some work was done * Returns: -1 on error, 0 nothing to do, n (>0) if some work was done
145 145 * timeout is in 1/1000 seconds increments. * timeout is in 1/1000 seconds increments.
146 146 */ */
147 int Conn_epoll_poll(const int timeout2, void (*cb)(struct Conn *C,
147 int Conn_epoll_poll(const int timeout2, void (*cb)(const unsigned int slot,
148 148 const int revents)) const int revents))
149 149 { {
150 150 int i, events; int i, events;
151 struct Conn *C;
152 151 unsigned int slot; unsigned int slot;
153 152
154 153 again: again:
 
... ... int Conn_epoll_poll(const int timeout2, void (*cb)(struct Conn *C,
171 170 Log(11, "Processing %d event(s)...\n", events); Log(11, "Processing %d event(s)...\n", events);
172 171 i = events - 1; i = events - 1;
173 172 do { do {
174 slot = (unsigned int) Conn_epoll_events[i].data.ptr;
175 C = &Conns[slot];
176 cb(C, Conn_epoll_events[i].events);
173 slot = Conn_epoll_events[i].data.u32;
174 cb(slot, Conn_epoll_events[i].events);
177 175
178 176 i--; i--;
179 177 } while (i >= 0); } while (i >= 0);
File Conn_engine_epoll.h changed (mode: 100644) (index b7631d5..b8597ef)
... ... extern int Conn_epoll_grow(unsigned int alloc);
13 13 extern int Conn_epoll_add_obj(struct Conn *C); extern int Conn_epoll_add_obj(struct Conn *C);
14 14 extern int Conn_epoll_del_obj(struct Conn *C); extern int Conn_epoll_del_obj(struct Conn *C);
15 15 extern int Conn_epoll_chg_obj(struct Conn *C); extern int Conn_epoll_chg_obj(struct Conn *C);
16 extern int Conn_epoll_poll(const int timeout2, void (*cb)(struct Conn *C,
16 extern int Conn_epoll_poll(const int timeout2, void (*cb)(const unsigned int slot,
17 17 const int revents)); const int revents));
18 18 extern int Conn_epoll_move_slot(const unsigned int dst, extern int Conn_epoll_move_slot(const unsigned int dst,
19 19 const unsigned int src); const unsigned int src);
File Conn_engine_poll.c changed (mode: 100644) (index e885b69..cdb9ad6)
... ... int Conn_poll_chg_obj(struct Conn *C)
99 99 * Returns: -1 on error, 0 nothing to do, n (>0) if some work was done * Returns: -1 on error, 0 nothing to do, n (>0) if some work was done
100 100 * timeout is in 1/1000 seconds increments. * timeout is in 1/1000 seconds increments.
101 101 */ */
102 int Conn_poll_poll(const int timeout2, void (*cb)(struct Conn *C,
102 int Conn_poll_poll(const int timeout2, void (*cb)(const unsigned int slot,
103 103 const int revents)) const int revents))
104 104 { {
105 int i, events;
105 int slot, events;
106 106
107 107 again: again:
108 108 events = poll(&Conn_poll_pfds[0], Conn_no, timeout2); events = poll(&Conn_poll_pfds[0], Conn_no, timeout2);
 
... ... int Conn_poll_poll(const int timeout2, void (*cb)(struct Conn *C,
125 125 /* We do revers scan because of moving Conn objects */ /* We do revers scan because of moving Conn objects */
126 126 Log(11, "Processing %d event(s)...\n", Log(11, "Processing %d event(s)...\n",
127 127 events); events);
128 i = Conn_no - 1;
128 slot = Conn_no - 1;
129 129 do { do {
130 if (Conn_poll_pfds[i].revents & POLLNVAL) {
130 if (Conn_poll_pfds[slot].revents & POLLNVAL) {
131 131 Log(0, "BUG NVAL!\n"); Log(0, "BUG NVAL!\n");
132 132 exit(1); exit(1);
133 133 } }
134 134
135 cb(&Conns[i], Conn_poll_pfds[i].revents);
135 cb(slot, Conn_poll_pfds[slot].revents);
136 136
137 i--;
138 } while (i >= 0);
137 slot--;
138 } while (slot >= 0);
139 139
140 140 return events; return events;
141 141
File Conn_engine_poll.h changed (mode: 100644) (index b518b20..183f7af)
... ... extern int Conn_poll_grow(unsigned int alloc);
13 13 extern int Conn_poll_add_obj(struct Conn *C); extern int Conn_poll_add_obj(struct Conn *C);
14 14 extern int Conn_poll_del_obj(struct Conn *C); extern int Conn_poll_del_obj(struct Conn *C);
15 15 extern int Conn_poll_chg_obj(struct Conn *C); extern int Conn_poll_chg_obj(struct Conn *C);
16 extern int Conn_poll_poll(const int timeout2, void (*cb)(struct Conn *C,
16 extern int Conn_poll_poll(const int timeout2, void (*cb)(const unsigned int slot,
17 17 const int revents)); const int revents));
18 18 extern int Conn_poll_move_slot(const unsigned int dst, extern int Conn_poll_move_slot(const unsigned int dst,
19 19 const unsigned int src); const unsigned int src);
File TODO changed (mode: 100644) (index 15e6dab..1425b11)
... ... Pentru a reduce numarul de conexiuni in TIME-WAIT:
60 60
61 61 === When we switch to Conn version 2 library === === When we switch to Conn version 2 library ===
62 62 [ ] Conn_socket will cann Conn_socket_proto [ ] Conn_socket will cann Conn_socket_proto
63 [ ] use enums!
File examples/Makefile changed (mode: 100644) (index 22c747d..69775e7)
1 TARGETS := s c raw udp_s timeout trigger reconnect ntime blackhole_s blackhole_c
1 TARGETS := s c raw udp_s timeout trigger reconnect ntime blackhole_s blackhole_c test1
2 2
3 3 all: $(TARGETS) all: $(TARGETS)
4 4
 
... ... blackhole_s: blackhole_s.c $(DEPS)
40 40 blackhole_c: blackhole_c.c $(DEPS) blackhole_c: blackhole_c.c $(DEPS)
41 41 gcc $(CFLAGS) $(INCS) $@.c -o $@ $(LIBS) -lrt gcc $(CFLAGS) $(INCS) $@.c -o $@ $(LIBS) -lrt
42 42
43 test1: test1.c $(DEPS)
44 gcc $(CFLAGS) $(INCS) $@.c -o $@ $(LIBS) -lrt
45
43 46 %: %.c $(DEPS) %: %.c $(DEPS)
44 47 gcc $(CFLAGS) $(INCS) $@.c -o $@ $(LIBS) gcc $(CFLAGS) $(INCS) $@.c -o $@ $(LIBS)
45 48
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/Conn

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/Conn

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/Conn

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main