connection_or.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /* Copyright 2001,2002 Roger Dingledine, Matej Pfajfar. */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. #include "or.h"
  5. extern or_options_t options; /* command-line and config-file options */
  6. /**************************************************************/
  7. static void cell_pack(char *dest, const cell_t *src) {
  8. *(uint16_t*)dest = htons(src->aci);
  9. *(uint8_t*)(dest+2) = src->command;
  10. *(uint8_t*)(dest+3) = src->length;
  11. *(uint32_t*)(dest+4) = 0; /* Reserved */
  12. memcpy(dest+8, src->payload, CELL_PAYLOAD_SIZE);
  13. }
  14. static void cell_unpack(cell_t *dest, const char *src) {
  15. dest->aci = ntohs(*(uint16_t*)(src));
  16. dest->command = *(uint8_t*)(src+2);
  17. dest->length = *(uint8_t*)(src+3);
  18. dest->seq = ntohl(*(uint32_t*)(src+4));
  19. memcpy(dest->payload, src+8, CELL_PAYLOAD_SIZE);
  20. }
  21. /**************************************************************/
  22. int connection_or_process_inbuf(connection_t *conn) {
  23. assert(conn && conn->type == CONN_TYPE_OR);
  24. if(conn->inbuf_reached_eof) {
  25. log_fn(LOG_INFO,"conn reached eof. Closing.");
  26. return -1;
  27. }
  28. if(conn->state != OR_CONN_STATE_OPEN)
  29. return 0; /* don't do anything */
  30. return connection_process_cell_from_inbuf(conn);
  31. }
  32. int connection_or_finished_flushing(connection_t *conn) {
  33. int e, len=sizeof(e);
  34. assert(conn && conn->type == CONN_TYPE_OR);
  35. switch(conn->state) {
  36. case OR_CONN_STATE_CONNECTING:
  37. if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
  38. if(!ERRNO_CONN_EINPROGRESS(errno)){
  39. log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
  40. return -1;
  41. } else {
  42. return 0; /* no change, see if next time is better */
  43. }
  44. }
  45. /* the connect has finished. */
  46. log_fn(LOG_INFO,"OR connect() to router %s:%u finished.",
  47. conn->address,conn->port);
  48. if(connection_tls_start_handshake(conn, 0) < 0)
  49. return -1;
  50. return 0;
  51. case OR_CONN_STATE_OPEN:
  52. connection_stop_writing(conn);
  53. return 0;
  54. default:
  55. log_fn(LOG_WARNING,"BUG: called in unexpected state.");
  56. return 0;
  57. }
  58. }
  59. /*********************/
  60. void connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *router) {
  61. conn->addr = router->addr;
  62. conn->port = router->or_port;
  63. conn->bandwidth = router->bandwidth;
  64. conn->onion_pkey = crypto_pk_dup_key(router->onion_pkey);
  65. conn->link_pkey = crypto_pk_dup_key(router->link_pkey);
  66. conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey);
  67. if(conn->address)
  68. free(conn->address);
  69. conn->address = strdup(router->address);
  70. }
  71. connection_t *connection_or_connect(routerinfo_t *router) {
  72. connection_t *conn;
  73. assert(router);
  74. if(router_is_me(router->addr, router->or_port)) {
  75. /* this is me! don't connect to me. XXX use nickname/key */
  76. log(LOG_DEBUG,"connection_or_connect(): This is me. Skipping.");
  77. return NULL;
  78. }
  79. /* this function should never be called if we're already connected to router, but */
  80. /* check first to be sure */
  81. conn = connection_exact_get_by_addr_port(router->addr,router->or_port);
  82. if(conn)
  83. return conn;
  84. conn = connection_new(CONN_TYPE_OR);
  85. if(!conn) {
  86. log_fn(LOG_WARNING,"connection_new failed; skipping.");
  87. return NULL;
  88. }
  89. /* set up conn so it's got all the data we need to remember */
  90. connection_or_init_conn_from_router(conn, router);
  91. if(connection_add(conn) < 0) { /* no space, forget it */
  92. connection_free(conn);
  93. return NULL;
  94. }
  95. switch(connection_connect(conn, router->address, router->addr, router->or_port)) {
  96. case -1:
  97. connection_remove(conn);
  98. connection_free(conn);
  99. return NULL;
  100. case 0:
  101. connection_set_poll_socket(conn);
  102. connection_watch_events(conn, POLLIN | POLLOUT | POLLERR);
  103. /* writable indicates finish, readable indicates broken link,
  104. error indicates broken link on windows */
  105. conn->state = OR_CONN_STATE_CONNECTING;
  106. return conn;
  107. /* case 1: fall through */
  108. }
  109. connection_set_poll_socket(conn);
  110. if(connection_tls_start_handshake(conn, 0) >= 0)
  111. return conn;
  112. /* failure */
  113. connection_remove(conn);
  114. connection_free(conn);
  115. return NULL;
  116. }
  117. /* ********************************** */
  118. int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
  119. char networkcell[CELL_NETWORK_SIZE];
  120. char *n = networkcell;
  121. cell_pack(n, cellp);
  122. return connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
  123. }
  124. /* if there's a whole cell there, pull it off and process it. */
  125. int connection_process_cell_from_inbuf(connection_t *conn) {
  126. char buf[CELL_NETWORK_SIZE];
  127. cell_t cell;
  128. log_fn(LOG_DEBUG,"%d: starting, inbuf_datalen %d.",conn->s,buf_datalen(conn->inbuf));
  129. if(buf_datalen(conn->inbuf) < CELL_NETWORK_SIZE) /* entire response available? */
  130. return 0; /* not yet */
  131. connection_fetch_from_buf(buf, CELL_NETWORK_SIZE, conn);
  132. /* retrieve cell info from buf (create the host-order struct from the network-order string) */
  133. cell_unpack(&cell, buf);
  134. command_process_cell(&cell, conn);
  135. return connection_process_inbuf(conn); /* process the remainder of the buffer */
  136. }
  137. /*
  138. Local Variables:
  139. mode:c
  140. indent-tabs-mode:nil
  141. c-basic-offset:2
  142. End:
  143. */