A clone of btpd with my configuration changes.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

118 wiersze
2.6 KiB

  1. #include "btpd.h"
  2. struct nameconn {
  3. struct fdev write_ev;
  4. void (*cb)(void *, int, int);
  5. void *arg;
  6. aictx_t ai_handle;
  7. struct addrinfo *ai_res, *ai_cur;
  8. int sd;
  9. enum { NC_AI, NC_CONN } state;
  10. };
  11. static void nc_connect(struct nameconn *nc);
  12. static void
  13. nc_free(struct nameconn *nc)
  14. {
  15. if (nc->ai_res != NULL)
  16. freeaddrinfo(nc->ai_res);
  17. free(nc);
  18. }
  19. static void
  20. nc_done(struct nameconn *nc, int error)
  21. {
  22. nc->cb(nc->arg, error, nc->sd);
  23. nc_free(nc);
  24. }
  25. static void
  26. nc_write_cb(int sd, short type, void *arg)
  27. {
  28. struct nameconn *nc = arg;
  29. int error;
  30. socklen_t errsiz = sizeof(int);
  31. if (getsockopt(nc->sd, SOL_SOCKET, SO_ERROR, &error, &errsiz) < 0)
  32. btpd_err("getsockopt error (%s).\n", strerror(errno));
  33. if (error == 0) {
  34. btpd_ev_del(&nc->write_ev);
  35. nc_done(nc, 0);
  36. } else {
  37. btpd_ev_del(&nc->write_ev);
  38. close(nc->sd);
  39. nc->ai_cur = nc->ai_cur->ai_next;
  40. nc_connect(nc);
  41. }
  42. }
  43. static void
  44. nc_connect(struct nameconn *nc)
  45. {
  46. struct addrinfo *ai;
  47. int err;
  48. again:
  49. if ((ai = nc->ai_cur) == NULL) {
  50. nc_done(nc, ENOTCONN);
  51. return;
  52. }
  53. if ((nc->sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
  54. btpd_err("Failed to create socket (%s).\n", strerror(errno));
  55. set_nonblocking(nc->sd);
  56. err = connect(nc->sd, ai->ai_addr, ai->ai_addrlen);
  57. if (err == 0)
  58. nc_done(nc, 0);
  59. else if (err < 0 && errno == EINPROGRESS)
  60. btpd_ev_new(&nc->write_ev, nc->sd, EV_WRITE, nc_write_cb, nc);
  61. else {
  62. close(nc->sd);
  63. nc->ai_cur = ai->ai_next;
  64. goto again;
  65. }
  66. }
  67. static void
  68. nc_ai_cb(void *arg, int error, struct addrinfo *ai)
  69. {
  70. struct nameconn *nc = arg;
  71. if (error == 0) {
  72. nc->ai_cur = nc->ai_res = ai;
  73. nc->state = NC_CONN;
  74. nc_connect(nc);
  75. } else
  76. nc_done(nc, error);
  77. }
  78. nameconn_t
  79. btpd_name_connect(const char *name, short port, void (*cb)(void *, int, int),
  80. void *arg)
  81. {
  82. struct addrinfo hints;
  83. struct nameconn *nc = btpd_calloc(1, sizeof(*nc));
  84. nc->cb = cb;
  85. nc->arg = arg;
  86. nc->sd = -1;
  87. bzero(&hints, sizeof(hints));
  88. hints.ai_flags = AI_ADDRCONFIG;
  89. hints.ai_family = net_af_spec();
  90. hints.ai_socktype = SOCK_STREAM;
  91. nc->ai_handle = btpd_addrinfo(name, port, &hints, nc_ai_cb, nc);
  92. return nc;
  93. }
  94. void
  95. btpd_name_connect_cancel(struct nameconn *nc)
  96. {
  97. if (nc->state == NC_AI)
  98. btpd_addrinfo_cancel(nc->ai_handle);
  99. else {
  100. btpd_ev_del(&nc->write_ev);
  101. close(nc->sd);
  102. }
  103. nc_free(nc);
  104. }