channel_bootstrap.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/io/channel_bootstrap.h>
  6. #include <aws/common/ref_count.h>
  7. #include <aws/common/string.h>
  8. #include <aws/io/event_loop.h>
  9. #include <aws/io/logging.h>
  10. #include <aws/io/socket.h>
  11. #include <aws/io/socket_channel_handler.h>
  12. #include <aws/io/tls_channel_handler.h>
  13. #ifdef _MSC_VER
  14. /* non-constant aggregate initializer */
  15. # pragma warning(disable : 4204)
  16. /* allow automatic variable to escape scope
  17. (it's intentional and we make sure it doesn't actually return
  18. before the task is finished).*/
  19. # pragma warning(disable : 4221)
  20. #endif
  21. static void s_client_bootstrap_destroy_impl(struct aws_client_bootstrap *bootstrap) {
  22. AWS_ASSERT(bootstrap);
  23. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: bootstrap destroying", (void *)bootstrap);
  24. aws_client_bootstrap_shutdown_complete_fn *on_shutdown_complete = bootstrap->on_shutdown_complete;
  25. void *user_data = bootstrap->user_data;
  26. aws_event_loop_group_release(bootstrap->event_loop_group);
  27. aws_host_resolver_release(bootstrap->host_resolver);
  28. aws_mem_release(bootstrap->allocator, bootstrap);
  29. if (on_shutdown_complete) {
  30. on_shutdown_complete(user_data);
  31. }
  32. }
  33. struct aws_client_bootstrap *aws_client_bootstrap_acquire(struct aws_client_bootstrap *bootstrap) {
  34. if (bootstrap != NULL) {
  35. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: acquiring bootstrap reference", (void *)bootstrap);
  36. aws_ref_count_acquire(&bootstrap->ref_count);
  37. }
  38. return bootstrap;
  39. }
  40. void aws_client_bootstrap_release(struct aws_client_bootstrap *bootstrap) {
  41. if (bootstrap != NULL) {
  42. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: releasing bootstrap reference", (void *)bootstrap);
  43. aws_ref_count_release(&bootstrap->ref_count);
  44. }
  45. }
  46. struct aws_client_bootstrap *aws_client_bootstrap_new(
  47. struct aws_allocator *allocator,
  48. const struct aws_client_bootstrap_options *options) {
  49. AWS_ASSERT(allocator);
  50. AWS_ASSERT(options);
  51. AWS_ASSERT(options->event_loop_group);
  52. struct aws_client_bootstrap *bootstrap = aws_mem_calloc(allocator, 1, sizeof(struct aws_client_bootstrap));
  53. if (!bootstrap) {
  54. return NULL;
  55. }
  56. AWS_LOGF_INFO(
  57. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  58. "id=%p: Initializing client bootstrap with event-loop group %p",
  59. (void *)bootstrap,
  60. (void *)options->event_loop_group);
  61. bootstrap->allocator = allocator;
  62. bootstrap->event_loop_group = aws_event_loop_group_acquire(options->event_loop_group);
  63. bootstrap->on_protocol_negotiated = NULL;
  64. aws_ref_count_init(
  65. &bootstrap->ref_count, bootstrap, (aws_simple_completion_callback *)s_client_bootstrap_destroy_impl);
  66. bootstrap->host_resolver = aws_host_resolver_acquire(options->host_resolver);
  67. bootstrap->on_shutdown_complete = options->on_shutdown_complete;
  68. bootstrap->user_data = options->user_data;
  69. if (options->host_resolution_config) {
  70. bootstrap->host_resolver_config = *options->host_resolution_config;
  71. } else {
  72. bootstrap->host_resolver_config = aws_host_resolver_init_default_resolution_config();
  73. }
  74. return bootstrap;
  75. }
  76. int aws_client_bootstrap_set_alpn_callback(
  77. struct aws_client_bootstrap *bootstrap,
  78. aws_channel_on_protocol_negotiated_fn *on_protocol_negotiated) {
  79. AWS_ASSERT(on_protocol_negotiated);
  80. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: Setting ALPN callback", (void *)bootstrap);
  81. bootstrap->on_protocol_negotiated = on_protocol_negotiated;
  82. return AWS_OP_SUCCESS;
  83. }
  84. struct client_channel_data {
  85. struct aws_channel *channel;
  86. struct aws_socket *socket;
  87. struct aws_tls_connection_options tls_options;
  88. aws_channel_on_protocol_negotiated_fn *on_protocol_negotiated;
  89. aws_tls_on_data_read_fn *user_on_data_read;
  90. aws_tls_on_negotiation_result_fn *user_on_negotiation_result;
  91. aws_tls_on_error_fn *user_on_error;
  92. void *tls_user_data;
  93. bool use_tls;
  94. };
  95. struct client_connection_args {
  96. struct aws_client_bootstrap *bootstrap;
  97. aws_client_bootstrap_on_channel_event_fn *creation_callback;
  98. aws_client_bootstrap_on_channel_event_fn *setup_callback;
  99. aws_client_bootstrap_on_channel_event_fn *shutdown_callback;
  100. struct client_channel_data channel_data;
  101. struct aws_socket_options outgoing_options;
  102. uint16_t outgoing_port;
  103. struct aws_string *host_name;
  104. void *user_data;
  105. uint8_t addresses_count;
  106. uint8_t failed_count;
  107. bool connection_chosen;
  108. bool setup_called;
  109. bool enable_read_back_pressure;
  110. struct aws_event_loop *requested_event_loop;
  111. /*
  112. * It is likely that all reference adjustments to the connection args take place in a single event loop
  113. * thread and are thus thread-safe. I can imagine some complex future scenarios where that might not hold true
  114. * and so it seems reasonable to switch now to a safe pattern.
  115. *
  116. */
  117. struct aws_ref_count ref_count;
  118. };
  119. static struct client_connection_args *s_client_connection_args_acquire(struct client_connection_args *args) {
  120. if (args != NULL) {
  121. AWS_LOGF_TRACE(AWS_LS_IO_CHANNEL_BOOTSTRAP, "acquiring client connection args, args=%p", (void *)args);
  122. aws_ref_count_acquire(&args->ref_count);
  123. }
  124. return args;
  125. }
  126. static void s_client_connection_args_destroy(struct client_connection_args *args) {
  127. AWS_ASSERT(args);
  128. AWS_LOGF_TRACE(AWS_LS_IO_CHANNEL_BOOTSTRAP, "destroying client connection args, args=%p", (void *)args);
  129. struct aws_allocator *allocator = args->bootstrap->allocator;
  130. aws_client_bootstrap_release(args->bootstrap);
  131. if (args->host_name) {
  132. aws_string_destroy(args->host_name);
  133. }
  134. if (args->channel_data.use_tls) {
  135. aws_tls_connection_options_clean_up(&args->channel_data.tls_options);
  136. }
  137. aws_mem_release(allocator, args);
  138. }
  139. static void s_client_connection_args_release(struct client_connection_args *args) {
  140. if (args != NULL) {
  141. AWS_LOGF_TRACE(AWS_LS_IO_CHANNEL_BOOTSTRAP, "releasing client connection args, args=%p", (void *)args);
  142. aws_ref_count_release(&args->ref_count);
  143. }
  144. }
  145. static struct aws_event_loop *s_get_connection_event_loop(struct client_connection_args *args) {
  146. if (args == NULL) {
  147. return NULL;
  148. }
  149. if (args->requested_event_loop != NULL) {
  150. return args->requested_event_loop;
  151. }
  152. return aws_event_loop_group_get_next_loop(args->bootstrap->event_loop_group);
  153. }
  154. static void s_connection_args_setup_callback(
  155. struct client_connection_args *args,
  156. int error_code,
  157. struct aws_channel *channel) {
  158. /* setup_callback is always called exactly once */
  159. AWS_FATAL_ASSERT(!args->setup_called);
  160. AWS_ASSERT((error_code == AWS_OP_SUCCESS) == (channel != NULL));
  161. aws_client_bootstrap_on_channel_event_fn *setup_callback = args->setup_callback;
  162. setup_callback(args->bootstrap, error_code, channel, args->user_data);
  163. args->setup_called = true;
  164. /* if setup_callback is called with an error, we will not call shutdown_callback */
  165. if (error_code) {
  166. args->shutdown_callback = NULL;
  167. }
  168. s_client_connection_args_release(args);
  169. }
  170. static void s_connection_args_creation_callback(struct client_connection_args *args, struct aws_channel *channel) {
  171. AWS_FATAL_ASSERT(channel != NULL);
  172. if (args->creation_callback) {
  173. args->creation_callback(args->bootstrap, AWS_ERROR_SUCCESS, channel, args->user_data);
  174. }
  175. }
  176. static void s_connection_args_shutdown_callback(
  177. struct client_connection_args *args,
  178. int error_code,
  179. struct aws_channel *channel) {
  180. if (!args->setup_called) {
  181. /* if setup_callback was not called yet, an error occurred, ensure we tell the user *SOMETHING* */
  182. error_code = (error_code) ? error_code : AWS_ERROR_UNKNOWN;
  183. s_connection_args_setup_callback(args, error_code, NULL);
  184. return;
  185. }
  186. aws_client_bootstrap_on_channel_event_fn *shutdown_callback = args->shutdown_callback;
  187. if (shutdown_callback) {
  188. shutdown_callback(args->bootstrap, error_code, channel, args->user_data);
  189. }
  190. }
  191. static void s_tls_client_on_negotiation_result(
  192. struct aws_channel_handler *handler,
  193. struct aws_channel_slot *slot,
  194. int err_code,
  195. void *user_data) {
  196. struct client_connection_args *connection_args = user_data;
  197. if (connection_args->channel_data.user_on_negotiation_result) {
  198. connection_args->channel_data.user_on_negotiation_result(
  199. handler, slot, err_code, connection_args->channel_data.tls_user_data);
  200. }
  201. AWS_LOGF_DEBUG(
  202. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  203. "id=%p: tls negotiation result %d on channel %p",
  204. (void *)connection_args->bootstrap,
  205. err_code,
  206. (void *)slot->channel);
  207. /* if an error occurred, the user callback will be delivered in shutdown */
  208. if (err_code) {
  209. aws_channel_shutdown(slot->channel, err_code);
  210. return;
  211. }
  212. struct aws_channel *channel = connection_args->channel_data.channel;
  213. s_connection_args_setup_callback(connection_args, AWS_ERROR_SUCCESS, channel);
  214. }
  215. /* in the context of a channel bootstrap, we don't care about these, but since we're hooking into these APIs we have to
  216. * provide a proxy for the user actually receiving their callbacks. */
  217. static void s_tls_client_on_data_read(
  218. struct aws_channel_handler *handler,
  219. struct aws_channel_slot *slot,
  220. struct aws_byte_buf *buffer,
  221. void *user_data) {
  222. struct client_connection_args *connection_args = user_data;
  223. if (connection_args->channel_data.user_on_data_read) {
  224. connection_args->channel_data.user_on_data_read(
  225. handler, slot, buffer, connection_args->channel_data.tls_user_data);
  226. }
  227. }
  228. /* in the context of a channel bootstrap, we don't care about these, but since we're hooking into these APIs we have to
  229. * provide a proxy for the user actually receiving their callbacks. */
  230. static void s_tls_client_on_error(
  231. struct aws_channel_handler *handler,
  232. struct aws_channel_slot *slot,
  233. int err,
  234. const char *message,
  235. void *user_data) {
  236. struct client_connection_args *connection_args = user_data;
  237. if (connection_args->channel_data.user_on_error) {
  238. connection_args->channel_data.user_on_error(
  239. handler, slot, err, message, connection_args->channel_data.tls_user_data);
  240. }
  241. }
  242. static inline int s_setup_client_tls(struct client_connection_args *connection_args, struct aws_channel *channel) {
  243. struct aws_channel_slot *tls_slot = aws_channel_slot_new(channel);
  244. /* as far as cleanup goes, since this stuff is being added to a channel, the caller will free this memory
  245. when they clean up the channel. */
  246. if (!tls_slot) {
  247. return AWS_OP_ERR;
  248. }
  249. struct aws_channel_handler *tls_handler = aws_tls_client_handler_new(
  250. connection_args->bootstrap->allocator, &connection_args->channel_data.tls_options, tls_slot);
  251. if (!tls_handler) {
  252. aws_mem_release(connection_args->bootstrap->allocator, (void *)tls_slot);
  253. return AWS_OP_ERR;
  254. }
  255. aws_channel_slot_insert_end(channel, tls_slot);
  256. AWS_LOGF_TRACE(
  257. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  258. "id=%p: Setting up client TLS on channel %p with handler %p on slot %p",
  259. (void *)connection_args->bootstrap,
  260. (void *)channel,
  261. (void *)tls_handler,
  262. (void *)tls_slot);
  263. if (aws_channel_slot_set_handler(tls_slot, tls_handler) != AWS_OP_SUCCESS) {
  264. return AWS_OP_ERR;
  265. }
  266. if (connection_args->channel_data.on_protocol_negotiated) {
  267. struct aws_channel_slot *alpn_slot = aws_channel_slot_new(channel);
  268. if (!alpn_slot) {
  269. return AWS_OP_ERR;
  270. }
  271. struct aws_channel_handler *alpn_handler = aws_tls_alpn_handler_new(
  272. connection_args->bootstrap->allocator,
  273. connection_args->channel_data.on_protocol_negotiated,
  274. connection_args->user_data);
  275. if (!alpn_handler) {
  276. aws_mem_release(connection_args->bootstrap->allocator, (void *)alpn_slot);
  277. return AWS_OP_ERR;
  278. }
  279. AWS_LOGF_TRACE(
  280. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  281. "id=%p: Setting up ALPN handler on channel "
  282. "%p with handler %p on slot %p",
  283. (void *)connection_args->bootstrap,
  284. (void *)channel,
  285. (void *)alpn_handler,
  286. (void *)alpn_slot);
  287. aws_channel_slot_insert_right(tls_slot, alpn_slot);
  288. if (aws_channel_slot_set_handler(alpn_slot, alpn_handler) != AWS_OP_SUCCESS) {
  289. return AWS_OP_ERR;
  290. }
  291. }
  292. if (aws_tls_client_handler_start_negotiation(tls_handler) != AWS_OP_SUCCESS) {
  293. return AWS_OP_ERR;
  294. }
  295. return AWS_OP_SUCCESS;
  296. }
  297. static void s_on_client_channel_on_setup_completed(struct aws_channel *channel, int error_code, void *user_data) {
  298. struct client_connection_args *connection_args = user_data;
  299. int err_code = error_code;
  300. if (!err_code) {
  301. AWS_LOGF_DEBUG(
  302. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  303. "id=%p: channel %p setup succeeded: bootstrapping.",
  304. (void *)connection_args->bootstrap,
  305. (void *)channel);
  306. struct aws_channel_slot *socket_slot = aws_channel_slot_new(channel);
  307. if (!socket_slot) {
  308. err_code = aws_last_error();
  309. goto error;
  310. }
  311. struct aws_channel_handler *socket_channel_handler = aws_socket_handler_new(
  312. connection_args->bootstrap->allocator,
  313. connection_args->channel_data.socket,
  314. socket_slot,
  315. g_aws_channel_max_fragment_size);
  316. if (!socket_channel_handler) {
  317. err_code = aws_last_error();
  318. aws_channel_slot_remove(socket_slot);
  319. socket_slot = NULL;
  320. goto error;
  321. }
  322. AWS_LOGF_TRACE(
  323. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  324. "id=%p: Setting up socket handler on channel "
  325. "%p with handler %p on slot %p.",
  326. (void *)connection_args->bootstrap,
  327. (void *)channel,
  328. (void *)socket_channel_handler,
  329. (void *)socket_slot);
  330. if (aws_channel_slot_set_handler(socket_slot, socket_channel_handler)) {
  331. err_code = aws_last_error();
  332. goto error;
  333. }
  334. if (connection_args->channel_data.use_tls) {
  335. /* we don't want to notify the user that the channel is ready yet, since tls is still negotiating, wait
  336. * for the negotiation callback and handle it then.*/
  337. if (s_setup_client_tls(connection_args, channel)) {
  338. err_code = aws_last_error();
  339. goto error;
  340. }
  341. } else {
  342. s_connection_args_setup_callback(connection_args, AWS_OP_SUCCESS, channel);
  343. }
  344. return;
  345. }
  346. error:
  347. AWS_LOGF_ERROR(
  348. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  349. "id=%p: channel %p setup failed with error %d.",
  350. (void *)connection_args->bootstrap,
  351. (void *)channel,
  352. err_code);
  353. aws_channel_shutdown(channel, err_code);
  354. /* the channel shutdown callback will clean the channel up */
  355. }
  356. static void s_on_client_channel_on_shutdown(struct aws_channel *channel, int error_code, void *user_data) {
  357. struct client_connection_args *connection_args = user_data;
  358. AWS_LOGF_DEBUG(
  359. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  360. "id=%p: channel %p shutdown with error %d.",
  361. (void *)connection_args->bootstrap,
  362. (void *)channel,
  363. error_code);
  364. /* note it's not safe to reference the bootstrap after the callback. */
  365. struct aws_allocator *allocator = connection_args->bootstrap->allocator;
  366. s_connection_args_shutdown_callback(connection_args, error_code, channel);
  367. aws_channel_destroy(channel);
  368. aws_socket_clean_up(connection_args->channel_data.socket);
  369. aws_mem_release(allocator, connection_args->channel_data.socket);
  370. s_client_connection_args_release(connection_args);
  371. }
  372. static bool s_aws_socket_domain_uses_dns(enum aws_socket_domain domain) {
  373. return domain == AWS_SOCKET_IPV4 || domain == AWS_SOCKET_IPV6;
  374. }
  375. static void s_on_client_connection_established(struct aws_socket *socket, int error_code, void *user_data) {
  376. struct client_connection_args *connection_args = user_data;
  377. AWS_LOGF_DEBUG(
  378. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  379. "id=%p: client connection on socket %p completed with error %d.",
  380. (void *)connection_args->bootstrap,
  381. (void *)socket,
  382. error_code);
  383. if (error_code) {
  384. connection_args->failed_count++;
  385. }
  386. if (error_code || connection_args->connection_chosen) {
  387. if (s_aws_socket_domain_uses_dns(connection_args->outgoing_options.domain) && error_code) {
  388. struct aws_host_address host_address;
  389. host_address.host = connection_args->host_name;
  390. host_address.address =
  391. aws_string_new_from_c_str(connection_args->bootstrap->allocator, socket->remote_endpoint.address);
  392. host_address.record_type = connection_args->outgoing_options.domain == AWS_SOCKET_IPV6
  393. ? AWS_ADDRESS_RECORD_TYPE_AAAA
  394. : AWS_ADDRESS_RECORD_TYPE_A;
  395. if (host_address.address) {
  396. AWS_LOGF_DEBUG(
  397. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  398. "id=%p: recording bad address %s.",
  399. (void *)connection_args->bootstrap,
  400. socket->remote_endpoint.address);
  401. aws_host_resolver_record_connection_failure(connection_args->bootstrap->host_resolver, &host_address);
  402. aws_string_destroy((void *)host_address.address);
  403. }
  404. }
  405. AWS_LOGF_TRACE(
  406. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  407. "id=%p: releasing socket %p either because we already have a "
  408. "successful connection or because it errored out.",
  409. (void *)connection_args->bootstrap,
  410. (void *)socket);
  411. aws_socket_close(socket);
  412. aws_socket_clean_up(socket);
  413. aws_mem_release(connection_args->bootstrap->allocator, socket);
  414. /* if this is the last attempted connection and it failed, notify the user */
  415. if (connection_args->failed_count == connection_args->addresses_count) {
  416. AWS_LOGF_ERROR(
  417. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  418. "id=%p: Connection failed with error_code %d.",
  419. (void *)connection_args->bootstrap,
  420. error_code);
  421. /* connection_args will be released after setup_callback */
  422. s_connection_args_setup_callback(connection_args, error_code, NULL);
  423. }
  424. /* every connection task adds a ref, so every failure or cancel needs to dec one */
  425. s_client_connection_args_release(connection_args);
  426. return;
  427. }
  428. connection_args->connection_chosen = true;
  429. connection_args->channel_data.socket = socket;
  430. struct aws_channel_options args = {
  431. .on_setup_completed = s_on_client_channel_on_setup_completed,
  432. .setup_user_data = connection_args,
  433. .shutdown_user_data = connection_args,
  434. .on_shutdown_completed = s_on_client_channel_on_shutdown,
  435. };
  436. args.enable_read_back_pressure = connection_args->enable_read_back_pressure;
  437. args.event_loop = aws_socket_get_event_loop(socket);
  438. AWS_LOGF_TRACE(
  439. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  440. "id=%p: Successful connection, creating a new channel using socket %p.",
  441. (void *)connection_args->bootstrap,
  442. (void *)socket);
  443. connection_args->channel_data.channel = aws_channel_new(connection_args->bootstrap->allocator, &args);
  444. if (!connection_args->channel_data.channel) {
  445. aws_socket_clean_up(socket);
  446. aws_mem_release(connection_args->bootstrap->allocator, connection_args->channel_data.socket);
  447. connection_args->failed_count++;
  448. /* if this is the last attempted connection and it failed, notify the user */
  449. if (connection_args->failed_count == connection_args->addresses_count) {
  450. s_connection_args_setup_callback(connection_args, error_code, NULL);
  451. }
  452. } else {
  453. s_connection_args_creation_callback(connection_args, connection_args->channel_data.channel);
  454. }
  455. }
  456. struct connection_task_data {
  457. struct aws_task task;
  458. struct aws_socket_endpoint endpoint;
  459. struct aws_socket_options options;
  460. struct aws_host_address host_address;
  461. struct client_connection_args *args;
  462. struct aws_event_loop *connect_loop;
  463. };
  464. static void s_attempt_connection(struct aws_task *task, void *arg, enum aws_task_status status) {
  465. (void)task;
  466. struct connection_task_data *task_data = arg;
  467. struct aws_allocator *allocator = task_data->args->bootstrap->allocator;
  468. int err_code = 0;
  469. if (status != AWS_TASK_STATUS_RUN_READY) {
  470. goto task_cancelled;
  471. }
  472. struct aws_socket *outgoing_socket = aws_mem_acquire(allocator, sizeof(struct aws_socket));
  473. if (!outgoing_socket) {
  474. goto socket_alloc_failed;
  475. }
  476. if (aws_socket_init(outgoing_socket, allocator, &task_data->options)) {
  477. goto socket_init_failed;
  478. }
  479. if (aws_socket_connect(
  480. outgoing_socket,
  481. &task_data->endpoint,
  482. task_data->connect_loop,
  483. s_on_client_connection_established,
  484. task_data->args)) {
  485. goto socket_connect_failed;
  486. }
  487. goto cleanup_task;
  488. socket_connect_failed:
  489. aws_host_resolver_record_connection_failure(task_data->args->bootstrap->host_resolver, &task_data->host_address);
  490. aws_socket_clean_up(outgoing_socket);
  491. socket_init_failed:
  492. aws_mem_release(allocator, outgoing_socket);
  493. socket_alloc_failed:
  494. err_code = aws_last_error();
  495. AWS_LOGF_ERROR(
  496. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  497. "id=%p: failed to create socket with error %d",
  498. (void *)task_data->args->bootstrap,
  499. err_code);
  500. task_cancelled:
  501. task_data->args->failed_count++;
  502. /* if this is the last attempted connection and it failed, notify the user */
  503. if (task_data->args->failed_count == task_data->args->addresses_count) {
  504. s_connection_args_setup_callback(task_data->args, err_code, NULL);
  505. }
  506. s_client_connection_args_release(task_data->args);
  507. cleanup_task:
  508. aws_host_address_clean_up(&task_data->host_address);
  509. aws_mem_release(allocator, task_data);
  510. }
  511. static void s_on_host_resolved(
  512. struct aws_host_resolver *resolver,
  513. const struct aws_string *host_name,
  514. int err_code,
  515. const struct aws_array_list *host_addresses,
  516. void *user_data) {
  517. (void)resolver;
  518. (void)host_name;
  519. struct client_connection_args *client_connection_args = user_data;
  520. struct aws_allocator *allocator = client_connection_args->bootstrap->allocator;
  521. if (err_code) {
  522. AWS_LOGF_ERROR(
  523. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  524. "id=%p: dns resolution failed, or all socket connections to the endpoint failed.",
  525. (void *)client_connection_args->bootstrap);
  526. s_connection_args_setup_callback(client_connection_args, err_code, NULL);
  527. return;
  528. }
  529. size_t host_addresses_len = aws_array_list_length(host_addresses);
  530. AWS_FATAL_ASSERT(host_addresses_len > 0);
  531. AWS_LOGF_TRACE(
  532. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  533. "id=%p: dns resolution completed. Kicking off connections"
  534. " on %llu addresses. First one back wins.",
  535. (void *)client_connection_args->bootstrap,
  536. (unsigned long long)host_addresses_len);
  537. /* use this event loop for all outgoing connection attempts (only one will ultimately win). */
  538. struct aws_event_loop *connect_loop = s_get_connection_event_loop(client_connection_args);
  539. client_connection_args->addresses_count = (uint8_t)host_addresses_len;
  540. /* allocate all the task data first, in case it fails... */
  541. AWS_VARIABLE_LENGTH_ARRAY(struct connection_task_data *, tasks, host_addresses_len);
  542. for (size_t i = 0; i < host_addresses_len; ++i) {
  543. struct connection_task_data *task_data = tasks[i] =
  544. aws_mem_calloc(allocator, 1, sizeof(struct connection_task_data));
  545. bool failed = task_data == NULL;
  546. if (!failed) {
  547. struct aws_host_address *host_address_ptr = NULL;
  548. aws_array_list_get_at_ptr(host_addresses, (void **)&host_address_ptr, i);
  549. task_data->endpoint.port = client_connection_args->outgoing_port;
  550. AWS_ASSERT(sizeof(task_data->endpoint.address) >= host_address_ptr->address->len + 1);
  551. memcpy(
  552. task_data->endpoint.address,
  553. aws_string_bytes(host_address_ptr->address),
  554. host_address_ptr->address->len);
  555. task_data->endpoint.address[host_address_ptr->address->len] = 0;
  556. task_data->options = client_connection_args->outgoing_options;
  557. task_data->options.domain =
  558. host_address_ptr->record_type == AWS_ADDRESS_RECORD_TYPE_AAAA ? AWS_SOCKET_IPV6 : AWS_SOCKET_IPV4;
  559. failed = aws_host_address_copy(host_address_ptr, &task_data->host_address) != AWS_OP_SUCCESS;
  560. task_data->args = client_connection_args;
  561. task_data->connect_loop = connect_loop;
  562. }
  563. if (failed) {
  564. for (size_t j = 0; j <= i; ++j) {
  565. if (tasks[j]) {
  566. aws_host_address_clean_up(&tasks[j]->host_address);
  567. aws_mem_release(allocator, tasks[j]);
  568. }
  569. }
  570. int alloc_err_code = aws_last_error();
  571. AWS_LOGF_ERROR(
  572. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  573. "id=%p: failed to allocate connection task data: err=%d",
  574. (void *)client_connection_args->bootstrap,
  575. alloc_err_code);
  576. s_connection_args_setup_callback(client_connection_args, alloc_err_code, NULL);
  577. return;
  578. }
  579. }
  580. /* ...then schedule all the tasks, which cannot fail */
  581. for (size_t i = 0; i < host_addresses_len; ++i) {
  582. struct connection_task_data *task_data = tasks[i];
  583. /**
  584. * Acquire on the connection args to make sure connection args outlive the tasks to attempt connection.
  585. *
  586. * Once upon a time, the connection attempt tasks were scheduled right after acquiring the connection args,
  587. * which lead to a crash that when the attempt connection tasks run and the attempt connection succeed and
  588. * closed before the other tasks can acquire on the connection args, the connection args had be destroyed before
  589. * acquire and lead to a crash.
  590. */
  591. s_client_connection_args_acquire(task_data->args);
  592. }
  593. for (size_t i = 0; i < host_addresses_len; ++i) {
  594. struct connection_task_data *task_data = tasks[i];
  595. aws_task_init(&task_data->task, s_attempt_connection, task_data, "attempt_connection");
  596. aws_event_loop_schedule_task_now(connect_loop, &task_data->task);
  597. }
  598. }
  599. static bool s_does_event_loop_belong_to_event_loop_group(
  600. struct aws_event_loop *loop,
  601. struct aws_event_loop_group *elg) {
  602. if (loop == NULL || elg == NULL) {
  603. return false;
  604. }
  605. size_t loop_count = aws_event_loop_group_get_loop_count(elg);
  606. for (size_t i = 0; i < loop_count; ++i) {
  607. struct aws_event_loop *elg_loop = aws_event_loop_group_get_loop_at(elg, i);
  608. if (elg_loop == loop) {
  609. return true;
  610. }
  611. }
  612. return false;
  613. }
  614. int aws_client_bootstrap_new_socket_channel(struct aws_socket_channel_bootstrap_options *options) {
  615. struct aws_client_bootstrap *bootstrap = options->bootstrap;
  616. AWS_FATAL_ASSERT(options->setup_callback);
  617. AWS_FATAL_ASSERT(options->shutdown_callback);
  618. AWS_FATAL_ASSERT(bootstrap);
  619. const struct aws_socket_options *socket_options = options->socket_options;
  620. AWS_FATAL_ASSERT(socket_options != NULL);
  621. const struct aws_tls_connection_options *tls_options = options->tls_options;
  622. AWS_FATAL_ASSERT(tls_options == NULL || socket_options->type == AWS_SOCKET_STREAM);
  623. aws_io_fatal_assert_library_initialized();
  624. if (options->requested_event_loop != NULL) {
  625. /* If we're asking for a specific event loop, verify it belongs to the bootstrap's event loop group */
  626. if (!(s_does_event_loop_belong_to_event_loop_group(
  627. options->requested_event_loop, bootstrap->event_loop_group))) {
  628. return aws_raise_error(AWS_ERROR_IO_PINNED_EVENT_LOOP_MISMATCH);
  629. }
  630. }
  631. struct client_connection_args *client_connection_args =
  632. aws_mem_calloc(bootstrap->allocator, 1, sizeof(struct client_connection_args));
  633. if (!client_connection_args) {
  634. return AWS_OP_ERR;
  635. }
  636. const char *host_name = options->host_name;
  637. uint16_t port = options->port;
  638. AWS_LOGF_TRACE(
  639. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  640. "id=%p: attempting to initialize a new client channel to %s:%d",
  641. (void *)bootstrap,
  642. host_name,
  643. (int)port);
  644. aws_ref_count_init(
  645. &client_connection_args->ref_count,
  646. client_connection_args,
  647. (aws_simple_completion_callback *)s_client_connection_args_destroy);
  648. client_connection_args->user_data = options->user_data;
  649. client_connection_args->bootstrap = aws_client_bootstrap_acquire(bootstrap);
  650. client_connection_args->creation_callback = options->creation_callback;
  651. client_connection_args->setup_callback = options->setup_callback;
  652. client_connection_args->shutdown_callback = options->shutdown_callback;
  653. client_connection_args->outgoing_options = *socket_options;
  654. client_connection_args->outgoing_port = port;
  655. client_connection_args->enable_read_back_pressure = options->enable_read_back_pressure;
  656. client_connection_args->requested_event_loop = options->requested_event_loop;
  657. if (tls_options) {
  658. if (aws_tls_connection_options_copy(&client_connection_args->channel_data.tls_options, tls_options)) {
  659. goto error;
  660. }
  661. client_connection_args->channel_data.use_tls = true;
  662. client_connection_args->channel_data.on_protocol_negotiated = bootstrap->on_protocol_negotiated;
  663. client_connection_args->channel_data.tls_user_data = tls_options->user_data;
  664. /* in order to honor any callbacks a user may have installed on their tls_connection_options,
  665. * we need to wrap them if they were set.*/
  666. if (bootstrap->on_protocol_negotiated) {
  667. client_connection_args->channel_data.tls_options.advertise_alpn_message = true;
  668. }
  669. if (tls_options->on_data_read) {
  670. client_connection_args->channel_data.user_on_data_read = tls_options->on_data_read;
  671. client_connection_args->channel_data.tls_options.on_data_read = s_tls_client_on_data_read;
  672. }
  673. if (tls_options->on_error) {
  674. client_connection_args->channel_data.user_on_error = tls_options->on_error;
  675. client_connection_args->channel_data.tls_options.on_error = s_tls_client_on_error;
  676. }
  677. if (tls_options->on_negotiation_result) {
  678. client_connection_args->channel_data.user_on_negotiation_result = tls_options->on_negotiation_result;
  679. }
  680. client_connection_args->channel_data.tls_options.on_negotiation_result = s_tls_client_on_negotiation_result;
  681. client_connection_args->channel_data.tls_options.user_data = client_connection_args;
  682. }
  683. if (s_aws_socket_domain_uses_dns(socket_options->domain)) {
  684. client_connection_args->host_name = aws_string_new_from_c_str(bootstrap->allocator, host_name);
  685. if (!client_connection_args->host_name) {
  686. goto error;
  687. }
  688. const struct aws_host_resolution_config *host_resolution_config = &bootstrap->host_resolver_config;
  689. if (options->host_resolution_override_config) {
  690. host_resolution_config = options->host_resolution_override_config;
  691. }
  692. if (aws_host_resolver_resolve_host(
  693. bootstrap->host_resolver,
  694. client_connection_args->host_name,
  695. s_on_host_resolved,
  696. host_resolution_config,
  697. client_connection_args)) {
  698. goto error;
  699. }
  700. } else {
  701. /* ensure that the pipe/domain socket name will fit in the endpoint address */
  702. const size_t host_name_len = strlen(host_name);
  703. if (host_name_len >= AWS_ADDRESS_MAX_LEN) {
  704. aws_raise_error(AWS_IO_SOCKET_INVALID_ADDRESS);
  705. goto error;
  706. }
  707. struct aws_socket_endpoint endpoint;
  708. AWS_ZERO_STRUCT(endpoint);
  709. memcpy(endpoint.address, host_name, host_name_len);
  710. if (socket_options->domain == AWS_SOCKET_VSOCK) {
  711. endpoint.port = port;
  712. } else {
  713. endpoint.port = 0;
  714. }
  715. struct aws_socket *outgoing_socket = aws_mem_acquire(bootstrap->allocator, sizeof(struct aws_socket));
  716. if (!outgoing_socket) {
  717. goto error;
  718. }
  719. if (aws_socket_init(outgoing_socket, bootstrap->allocator, socket_options)) {
  720. aws_mem_release(bootstrap->allocator, outgoing_socket);
  721. goto error;
  722. }
  723. client_connection_args->addresses_count = 1;
  724. struct aws_event_loop *connect_loop = s_get_connection_event_loop(client_connection_args);
  725. s_client_connection_args_acquire(client_connection_args);
  726. if (aws_socket_connect(
  727. outgoing_socket, &endpoint, connect_loop, s_on_client_connection_established, client_connection_args)) {
  728. aws_socket_clean_up(outgoing_socket);
  729. aws_mem_release(client_connection_args->bootstrap->allocator, outgoing_socket);
  730. s_client_connection_args_release(client_connection_args);
  731. goto error;
  732. }
  733. }
  734. return AWS_OP_SUCCESS;
  735. error:
  736. if (client_connection_args) {
  737. /* tls opt will also be freed when we clean up the connection arg */
  738. s_client_connection_args_release(client_connection_args);
  739. }
  740. return AWS_OP_ERR;
  741. }
  742. void s_server_bootstrap_destroy_impl(struct aws_server_bootstrap *bootstrap) {
  743. AWS_ASSERT(bootstrap);
  744. aws_event_loop_group_release(bootstrap->event_loop_group);
  745. aws_mem_release(bootstrap->allocator, bootstrap);
  746. }
  747. struct aws_server_bootstrap *aws_server_bootstrap_acquire(struct aws_server_bootstrap *bootstrap) {
  748. if (bootstrap != NULL) {
  749. aws_ref_count_acquire(&bootstrap->ref_count);
  750. }
  751. return bootstrap;
  752. }
  753. void aws_server_bootstrap_release(struct aws_server_bootstrap *bootstrap) {
  754. /* if destroy is being called, the user intends to not use the bootstrap anymore
  755. * so we clean up the thread local state while the event loop thread is
  756. * still alive */
  757. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: releasing server bootstrap reference", (void *)bootstrap);
  758. if (bootstrap != NULL) {
  759. aws_ref_count_release(&bootstrap->ref_count);
  760. }
  761. }
  762. struct aws_server_bootstrap *aws_server_bootstrap_new(
  763. struct aws_allocator *allocator,
  764. struct aws_event_loop_group *el_group) {
  765. AWS_ASSERT(allocator);
  766. AWS_ASSERT(el_group);
  767. struct aws_server_bootstrap *bootstrap = aws_mem_calloc(allocator, 1, sizeof(struct aws_server_bootstrap));
  768. if (!bootstrap) {
  769. return NULL;
  770. }
  771. AWS_LOGF_INFO(
  772. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  773. "id=%p: Initializing server bootstrap with event-loop group %p",
  774. (void *)bootstrap,
  775. (void *)el_group);
  776. bootstrap->allocator = allocator;
  777. bootstrap->event_loop_group = aws_event_loop_group_acquire(el_group);
  778. bootstrap->on_protocol_negotiated = NULL;
  779. aws_ref_count_init(
  780. &bootstrap->ref_count, bootstrap, (aws_simple_completion_callback *)s_server_bootstrap_destroy_impl);
  781. return bootstrap;
  782. }
  783. struct server_connection_args {
  784. struct aws_server_bootstrap *bootstrap;
  785. struct aws_socket listener;
  786. aws_server_bootstrap_on_accept_channel_setup_fn *incoming_callback;
  787. aws_server_bootstrap_on_accept_channel_shutdown_fn *shutdown_callback;
  788. aws_server_bootstrap_on_server_listener_destroy_fn *destroy_callback;
  789. struct aws_tls_connection_options tls_options;
  790. aws_channel_on_protocol_negotiated_fn *on_protocol_negotiated;
  791. aws_tls_on_data_read_fn *user_on_data_read;
  792. aws_tls_on_negotiation_result_fn *user_on_negotiation_result;
  793. aws_tls_on_error_fn *user_on_error;
  794. struct aws_task listener_destroy_task;
  795. void *tls_user_data;
  796. void *user_data;
  797. bool use_tls;
  798. bool enable_read_back_pressure;
  799. struct aws_ref_count ref_count;
  800. };
  801. struct server_channel_data {
  802. struct aws_channel *channel;
  803. struct aws_socket *socket;
  804. struct server_connection_args *server_connection_args;
  805. bool incoming_called;
  806. };
  807. static struct server_connection_args *s_server_connection_args_acquire(struct server_connection_args *args) {
  808. if (args != NULL) {
  809. aws_ref_count_acquire(&args->ref_count);
  810. }
  811. return args;
  812. }
  813. static void s_server_connection_args_destroy(struct server_connection_args *args) {
  814. if (args == NULL) {
  815. return;
  816. }
  817. /* fire the destroy callback */
  818. if (args->destroy_callback) {
  819. args->destroy_callback(args->bootstrap, args->user_data);
  820. }
  821. struct aws_allocator *allocator = args->bootstrap->allocator;
  822. aws_server_bootstrap_release(args->bootstrap);
  823. if (args->use_tls) {
  824. aws_tls_connection_options_clean_up(&args->tls_options);
  825. }
  826. aws_mem_release(allocator, args);
  827. }
  828. static void s_server_connection_args_release(struct server_connection_args *args) {
  829. if (args != NULL) {
  830. aws_ref_count_release(&args->ref_count);
  831. }
  832. }
  833. static void s_server_incoming_callback(
  834. struct server_channel_data *channel_data,
  835. int error_code,
  836. struct aws_channel *channel) {
  837. /* incoming_callback is always called exactly once for each channel */
  838. AWS_ASSERT(!channel_data->incoming_called);
  839. struct server_connection_args *args = channel_data->server_connection_args;
  840. args->incoming_callback(args->bootstrap, error_code, channel, args->user_data);
  841. channel_data->incoming_called = true;
  842. }
  843. static void s_tls_server_on_negotiation_result(
  844. struct aws_channel_handler *handler,
  845. struct aws_channel_slot *slot,
  846. int err_code,
  847. void *user_data) {
  848. struct server_channel_data *channel_data = user_data;
  849. struct server_connection_args *connection_args = channel_data->server_connection_args;
  850. if (connection_args->user_on_negotiation_result) {
  851. connection_args->user_on_negotiation_result(handler, slot, err_code, connection_args->tls_user_data);
  852. }
  853. AWS_LOGF_DEBUG(
  854. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  855. "id=%p: tls negotiation result %d on channel %p",
  856. (void *)connection_args->bootstrap,
  857. err_code,
  858. (void *)slot->channel);
  859. struct aws_channel *channel = slot->channel;
  860. if (err_code) {
  861. /* shut down the channel */
  862. aws_channel_shutdown(channel, err_code);
  863. } else {
  864. s_server_incoming_callback(channel_data, err_code, channel);
  865. }
  866. }
  867. /* in the context of a channel bootstrap, we don't care about these, but since we're hooking into these APIs we have to
  868. * provide a proxy for the user actually receiving their callbacks. */
  869. static void s_tls_server_on_data_read(
  870. struct aws_channel_handler *handler,
  871. struct aws_channel_slot *slot,
  872. struct aws_byte_buf *buffer,
  873. void *user_data) {
  874. struct server_connection_args *connection_args = user_data;
  875. if (connection_args->user_on_data_read) {
  876. connection_args->user_on_data_read(handler, slot, buffer, connection_args->tls_user_data);
  877. }
  878. }
  879. /* in the context of a channel bootstrap, we don't care about these, but since we're hooking into these APIs we have to
  880. * provide a proxy for the user actually receiving their callbacks. */
  881. static void s_tls_server_on_error(
  882. struct aws_channel_handler *handler,
  883. struct aws_channel_slot *slot,
  884. int err,
  885. const char *message,
  886. void *user_data) {
  887. struct server_connection_args *connection_args = user_data;
  888. if (connection_args->user_on_error) {
  889. connection_args->user_on_error(handler, slot, err, message, connection_args->tls_user_data);
  890. }
  891. }
  892. static inline int s_setup_server_tls(struct server_channel_data *channel_data, struct aws_channel *channel) {
  893. struct aws_channel_slot *tls_slot = NULL;
  894. struct aws_channel_handler *tls_handler = NULL;
  895. struct server_connection_args *connection_args = channel_data->server_connection_args;
  896. /* as far as cleanup goes here, since we're adding things to a channel, if a slot is ever successfully
  897. added to the channel, we leave it there. The caller will clean up the channel and it will clean this memory
  898. up as well. */
  899. tls_slot = aws_channel_slot_new(channel);
  900. if (!tls_slot) {
  901. return AWS_OP_ERR;
  902. }
  903. /* Shallow-copy tls_options so we can override the user_data, making it specific to this channel */
  904. struct aws_tls_connection_options tls_options = connection_args->tls_options;
  905. tls_options.user_data = channel_data;
  906. tls_handler = aws_tls_server_handler_new(connection_args->bootstrap->allocator, &tls_options, tls_slot);
  907. if (!tls_handler) {
  908. aws_mem_release(connection_args->bootstrap->allocator, tls_slot);
  909. return AWS_OP_ERR;
  910. }
  911. AWS_LOGF_TRACE(
  912. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  913. "id=%p: Setting up server TLS on channel %p with handler %p on slot %p",
  914. (void *)connection_args->bootstrap,
  915. (void *)channel,
  916. (void *)tls_handler,
  917. (void *)tls_slot);
  918. aws_channel_slot_insert_end(channel, tls_slot);
  919. if (aws_channel_slot_set_handler(tls_slot, tls_handler)) {
  920. return AWS_OP_ERR;
  921. }
  922. if (connection_args->on_protocol_negotiated) {
  923. struct aws_channel_slot *alpn_slot = NULL;
  924. struct aws_channel_handler *alpn_handler = NULL;
  925. alpn_slot = aws_channel_slot_new(channel);
  926. if (!alpn_slot) {
  927. return AWS_OP_ERR;
  928. }
  929. alpn_handler = aws_tls_alpn_handler_new(
  930. connection_args->bootstrap->allocator, connection_args->on_protocol_negotiated, connection_args->user_data);
  931. if (!alpn_handler) {
  932. aws_channel_slot_remove(alpn_slot);
  933. return AWS_OP_ERR;
  934. }
  935. AWS_LOGF_TRACE(
  936. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  937. "id=%p: Setting up ALPN handler on channel "
  938. "%p with handler %p on slot %p",
  939. (void *)connection_args->bootstrap,
  940. (void *)channel,
  941. (void *)alpn_handler,
  942. (void *)alpn_slot);
  943. aws_channel_slot_insert_right(tls_slot, alpn_slot);
  944. if (aws_channel_slot_set_handler(alpn_slot, alpn_handler)) {
  945. return AWS_OP_ERR;
  946. }
  947. }
  948. /*
  949. * Server-side channels can reach this point in execution and actually have the CLIENT_HELLO payload already
  950. * on the socket in a signalled state, but there was no socket handler or read handler at the time of signal.
  951. * So we need to manually trigger a read here to cover that case, otherwise the negotiation will time out because
  952. * we will not receive any more data/notifications (unless we read and react).
  953. */
  954. if (aws_channel_trigger_read(channel)) {
  955. return AWS_OP_ERR;
  956. }
  957. return AWS_OP_SUCCESS;
  958. }
  959. static void s_on_server_channel_on_setup_completed(struct aws_channel *channel, int error_code, void *user_data) {
  960. struct server_channel_data *channel_data = user_data;
  961. int err_code = error_code;
  962. if (err_code) {
  963. /* channel fail to set up no destroy callback will fire */
  964. AWS_LOGF_ERROR(
  965. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  966. "id=%p: channel %p setup failed with error %d.",
  967. (void *)channel_data->server_connection_args->bootstrap,
  968. (void *)channel,
  969. err_code);
  970. aws_channel_destroy(channel);
  971. struct aws_allocator *allocator = channel_data->socket->allocator;
  972. aws_socket_clean_up(channel_data->socket);
  973. aws_mem_release(allocator, (void *)channel_data->socket);
  974. s_server_incoming_callback(channel_data, err_code, NULL);
  975. aws_mem_release(channel_data->server_connection_args->bootstrap->allocator, channel_data);
  976. /* no shutdown call back will be fired, we release the ref_count of connection arg here */
  977. s_server_connection_args_release(channel_data->server_connection_args);
  978. return;
  979. }
  980. AWS_LOGF_DEBUG(
  981. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  982. "id=%p: channel %p setup succeeded: bootstrapping.",
  983. (void *)channel_data->server_connection_args->bootstrap,
  984. (void *)channel);
  985. struct aws_channel_slot *socket_slot = aws_channel_slot_new(channel);
  986. if (!socket_slot) {
  987. err_code = aws_last_error();
  988. goto error;
  989. }
  990. struct aws_channel_handler *socket_channel_handler = aws_socket_handler_new(
  991. channel_data->server_connection_args->bootstrap->allocator,
  992. channel_data->socket,
  993. socket_slot,
  994. g_aws_channel_max_fragment_size);
  995. if (!socket_channel_handler) {
  996. err_code = aws_last_error();
  997. aws_channel_slot_remove(socket_slot);
  998. socket_slot = NULL;
  999. goto error;
  1000. }
  1001. AWS_LOGF_TRACE(
  1002. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  1003. "id=%p: Setting up socket handler on channel "
  1004. "%p with handler %p on slot %p.",
  1005. (void *)channel_data->server_connection_args->bootstrap,
  1006. (void *)channel,
  1007. (void *)socket_channel_handler,
  1008. (void *)socket_slot);
  1009. if (aws_channel_slot_set_handler(socket_slot, socket_channel_handler)) {
  1010. err_code = aws_last_error();
  1011. goto error;
  1012. }
  1013. if (channel_data->server_connection_args->use_tls) {
  1014. /* incoming callback will be invoked upon the negotiation completion so don't do it
  1015. * here. */
  1016. if (s_setup_server_tls(channel_data, channel)) {
  1017. err_code = aws_last_error();
  1018. goto error;
  1019. }
  1020. } else {
  1021. s_server_incoming_callback(channel_data, AWS_OP_SUCCESS, channel);
  1022. }
  1023. return;
  1024. error:
  1025. /* shut down the channel */
  1026. aws_channel_shutdown(channel, err_code);
  1027. }
  1028. static void s_on_server_channel_on_shutdown(struct aws_channel *channel, int error_code, void *user_data) {
  1029. struct server_channel_data *channel_data = user_data;
  1030. struct server_connection_args *args = channel_data->server_connection_args;
  1031. AWS_LOGF_DEBUG(
  1032. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  1033. "id=%p: channel %p shutdown with error %d.",
  1034. (void *)args->bootstrap,
  1035. (void *)channel,
  1036. error_code);
  1037. void *server_shutdown_user_data = args->user_data;
  1038. struct aws_server_bootstrap *server_bootstrap = args->bootstrap;
  1039. struct aws_allocator *allocator = server_bootstrap->allocator;
  1040. if (!channel_data->incoming_called) {
  1041. error_code = (error_code) ? error_code : AWS_ERROR_UNKNOWN;
  1042. s_server_incoming_callback(channel_data, error_code, NULL);
  1043. } else {
  1044. args->shutdown_callback(server_bootstrap, error_code, channel, server_shutdown_user_data);
  1045. }
  1046. aws_channel_destroy(channel);
  1047. aws_socket_clean_up(channel_data->socket);
  1048. aws_mem_release(allocator, channel_data->socket);
  1049. s_server_connection_args_release(channel_data->server_connection_args);
  1050. aws_mem_release(allocator, channel_data);
  1051. }
  1052. void s_on_server_connection_result(
  1053. struct aws_socket *socket,
  1054. int error_code,
  1055. struct aws_socket *new_socket,
  1056. void *user_data) {
  1057. (void)socket;
  1058. struct server_connection_args *connection_args = user_data;
  1059. s_server_connection_args_acquire(connection_args);
  1060. AWS_LOGF_DEBUG(
  1061. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  1062. "id=%p: server connection on socket %p completed with error %d.",
  1063. (void *)connection_args->bootstrap,
  1064. (void *)socket,
  1065. error_code);
  1066. if (!error_code) {
  1067. AWS_LOGF_TRACE(
  1068. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  1069. "id=%p: creating a new channel for incoming "
  1070. "connection using socket %p.",
  1071. (void *)connection_args->bootstrap,
  1072. (void *)socket);
  1073. struct server_channel_data *channel_data =
  1074. aws_mem_calloc(connection_args->bootstrap->allocator, 1, sizeof(struct server_channel_data));
  1075. if (!channel_data) {
  1076. goto error_cleanup;
  1077. }
  1078. channel_data->incoming_called = false;
  1079. channel_data->socket = new_socket;
  1080. channel_data->server_connection_args = connection_args;
  1081. struct aws_event_loop *event_loop =
  1082. aws_event_loop_group_get_next_loop(connection_args->bootstrap->event_loop_group);
  1083. struct aws_channel_options channel_args = {
  1084. .on_setup_completed = s_on_server_channel_on_setup_completed,
  1085. .setup_user_data = channel_data,
  1086. .shutdown_user_data = channel_data,
  1087. .on_shutdown_completed = s_on_server_channel_on_shutdown,
  1088. };
  1089. channel_args.event_loop = event_loop;
  1090. channel_args.enable_read_back_pressure = channel_data->server_connection_args->enable_read_back_pressure;
  1091. if (aws_socket_assign_to_event_loop(new_socket, event_loop)) {
  1092. aws_mem_release(connection_args->bootstrap->allocator, (void *)channel_data);
  1093. goto error_cleanup;
  1094. }
  1095. channel_data->channel = aws_channel_new(connection_args->bootstrap->allocator, &channel_args);
  1096. if (!channel_data->channel) {
  1097. aws_mem_release(connection_args->bootstrap->allocator, (void *)channel_data);
  1098. goto error_cleanup;
  1099. }
  1100. } else {
  1101. /* no channel is created */
  1102. connection_args->incoming_callback(connection_args->bootstrap, error_code, NULL, connection_args->user_data);
  1103. s_server_connection_args_release(connection_args);
  1104. }
  1105. return;
  1106. error_cleanup:
  1107. /* no channel is created */
  1108. connection_args->incoming_callback(connection_args->bootstrap, aws_last_error(), NULL, connection_args->user_data);
  1109. struct aws_allocator *allocator = new_socket->allocator;
  1110. aws_socket_clean_up(new_socket);
  1111. aws_mem_release(allocator, (void *)new_socket);
  1112. s_server_connection_args_release(connection_args);
  1113. }
  1114. static void s_listener_destroy_task(struct aws_task *task, void *arg, enum aws_task_status status) {
  1115. (void)status;
  1116. (void)task;
  1117. struct server_connection_args *server_connection_args = arg;
  1118. aws_socket_stop_accept(&server_connection_args->listener);
  1119. aws_socket_clean_up(&server_connection_args->listener);
  1120. s_server_connection_args_release(server_connection_args);
  1121. }
  1122. struct aws_socket *aws_server_bootstrap_new_socket_listener(
  1123. const struct aws_server_socket_channel_bootstrap_options *bootstrap_options) {
  1124. AWS_PRECONDITION(bootstrap_options);
  1125. AWS_PRECONDITION(bootstrap_options->bootstrap);
  1126. AWS_PRECONDITION(bootstrap_options->incoming_callback);
  1127. AWS_PRECONDITION(bootstrap_options->shutdown_callback);
  1128. struct server_connection_args *server_connection_args =
  1129. aws_mem_calloc(bootstrap_options->bootstrap->allocator, 1, sizeof(struct server_connection_args));
  1130. if (!server_connection_args) {
  1131. return NULL;
  1132. }
  1133. AWS_LOGF_INFO(
  1134. AWS_LS_IO_CHANNEL_BOOTSTRAP,
  1135. "id=%p: attempting to initialize a new "
  1136. "server socket listener for %s:%d",
  1137. (void *)bootstrap_options->bootstrap,
  1138. bootstrap_options->host_name,
  1139. (int)bootstrap_options->port);
  1140. aws_ref_count_init(
  1141. &server_connection_args->ref_count,
  1142. server_connection_args,
  1143. (aws_simple_completion_callback *)s_server_connection_args_destroy);
  1144. server_connection_args->user_data = bootstrap_options->user_data;
  1145. server_connection_args->bootstrap = aws_server_bootstrap_acquire(bootstrap_options->bootstrap);
  1146. server_connection_args->shutdown_callback = bootstrap_options->shutdown_callback;
  1147. server_connection_args->incoming_callback = bootstrap_options->incoming_callback;
  1148. server_connection_args->destroy_callback = bootstrap_options->destroy_callback;
  1149. server_connection_args->on_protocol_negotiated = bootstrap_options->bootstrap->on_protocol_negotiated;
  1150. server_connection_args->enable_read_back_pressure = bootstrap_options->enable_read_back_pressure;
  1151. aws_task_init(
  1152. &server_connection_args->listener_destroy_task,
  1153. s_listener_destroy_task,
  1154. server_connection_args,
  1155. "listener socket destroy");
  1156. if (bootstrap_options->tls_options) {
  1157. AWS_LOGF_INFO(
  1158. AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: using tls on listener", (void *)bootstrap_options->tls_options);
  1159. if (aws_tls_connection_options_copy(&server_connection_args->tls_options, bootstrap_options->tls_options)) {
  1160. goto cleanup_server_connection_args;
  1161. }
  1162. server_connection_args->use_tls = true;
  1163. server_connection_args->tls_user_data = bootstrap_options->tls_options->user_data;
  1164. /* in order to honor any callbacks a user may have installed on their tls_connection_options,
  1165. * we need to wrap them if they were set.*/
  1166. if (bootstrap_options->bootstrap->on_protocol_negotiated) {
  1167. server_connection_args->tls_options.advertise_alpn_message = true;
  1168. }
  1169. if (bootstrap_options->tls_options->on_data_read) {
  1170. server_connection_args->user_on_data_read = bootstrap_options->tls_options->on_data_read;
  1171. server_connection_args->tls_options.on_data_read = s_tls_server_on_data_read;
  1172. }
  1173. if (bootstrap_options->tls_options->on_error) {
  1174. server_connection_args->user_on_error = bootstrap_options->tls_options->on_error;
  1175. server_connection_args->tls_options.on_error = s_tls_server_on_error;
  1176. }
  1177. if (bootstrap_options->tls_options->on_negotiation_result) {
  1178. server_connection_args->user_on_negotiation_result = bootstrap_options->tls_options->on_negotiation_result;
  1179. }
  1180. server_connection_args->tls_options.on_negotiation_result = s_tls_server_on_negotiation_result;
  1181. server_connection_args->tls_options.user_data = server_connection_args;
  1182. }
  1183. struct aws_event_loop *connection_loop =
  1184. aws_event_loop_group_get_next_loop(bootstrap_options->bootstrap->event_loop_group);
  1185. if (aws_socket_init(
  1186. &server_connection_args->listener,
  1187. bootstrap_options->bootstrap->allocator,
  1188. bootstrap_options->socket_options)) {
  1189. goto cleanup_server_connection_args;
  1190. }
  1191. struct aws_socket_endpoint endpoint;
  1192. AWS_ZERO_STRUCT(endpoint);
  1193. size_t host_name_len = 0;
  1194. if (aws_secure_strlen(bootstrap_options->host_name, sizeof(endpoint.address), &host_name_len)) {
  1195. goto cleanup_server_connection_args;
  1196. }
  1197. memcpy(endpoint.address, bootstrap_options->host_name, host_name_len);
  1198. endpoint.port = bootstrap_options->port;
  1199. if (aws_socket_bind(&server_connection_args->listener, &endpoint)) {
  1200. goto cleanup_listener;
  1201. }
  1202. if (aws_socket_listen(&server_connection_args->listener, 1024)) {
  1203. goto cleanup_listener;
  1204. }
  1205. if (aws_socket_start_accept(
  1206. &server_connection_args->listener,
  1207. connection_loop,
  1208. s_on_server_connection_result,
  1209. server_connection_args)) {
  1210. goto cleanup_listener;
  1211. }
  1212. return &server_connection_args->listener;
  1213. cleanup_listener:
  1214. aws_socket_clean_up(&server_connection_args->listener);
  1215. cleanup_server_connection_args:
  1216. s_server_connection_args_release(server_connection_args);
  1217. return NULL;
  1218. }
  1219. void aws_server_bootstrap_destroy_socket_listener(struct aws_server_bootstrap *bootstrap, struct aws_socket *listener) {
  1220. struct server_connection_args *server_connection_args =
  1221. AWS_CONTAINER_OF(listener, struct server_connection_args, listener);
  1222. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: releasing bootstrap reference", (void *)bootstrap);
  1223. aws_event_loop_schedule_task_now(listener->event_loop, &server_connection_args->listener_destroy_task);
  1224. }
  1225. int aws_server_bootstrap_set_alpn_callback(
  1226. struct aws_server_bootstrap *bootstrap,
  1227. aws_channel_on_protocol_negotiated_fn *on_protocol_negotiated) {
  1228. AWS_ASSERT(on_protocol_negotiated);
  1229. AWS_LOGF_DEBUG(AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: Setting ALPN callback", (void *)bootstrap);
  1230. bootstrap->on_protocol_negotiated = on_protocol_negotiated;
  1231. return AWS_OP_SUCCESS;
  1232. }