A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

118 lignes
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. }