Skip to content

Instantly share code, notes, and snippets.

Created March 22, 2012 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2158903 to your computer and use it in GitHub Desktop.
Save anonymous/2158903 to your computer and use it in GitHub Desktop.
//
// main.c
// UVDickery
//
// Created by Dylan Lukes on 3/21/12.
// Copyright (c) 2012 Dylan Lukes. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include "uv.h"
/* structs */
typedef struct {
struct addrinfo *ai0;
struct addrinfo *ai;
} connect_req_state_t;
/* prototypes */
void gai_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo *res0);
void try_next_addrinfo(connect_req_state_t *req_state);
void connect_cb(uv_connect_t *req, int status);
/* statics */
static uv_loop_t *my_loop;
/* implementations */
void gai_cb(uv_getaddrinfo_t* handle, int status, struct addrinfo *ai0)
{
if (status != 0) {
fprintf(stderr, "uv_getaddrinfo: fatal: %s\n", gai_strerror(status));
exit(EXIT_FAILURE);
}
connect_req_state_t *state = calloc(1, sizeof(connect_req_state_t));
state->ai0 = ai0;
state->ai = ai0;
try_next_addrinfo(state);
free(handle);
}
void try_next_addrinfo(connect_req_state_t *state)
{
uv_tcp_t *tcp_handle = calloc(1, sizeof(uv_tcp_t));
uv_tcp_init(my_loop, tcp_handle);
uv_connect_t *connect_req = calloc(1, sizeof(uv_connect_t));
if (state->ai->ai_family == AF_INET) {
uv_tcp_connect(connect_req, tcp_handle, *(struct sockaddr_in *)state->ai->ai_addr, connect_cb);
} else if (state->ai->ai_family == AF_INET6) {
uv_tcp_connect6(connect_req, tcp_handle, *(struct sockaddr_in6 *)state->ai->ai_addr, connect_cb);
} else {
fprintf(stderr, "try_next_ai: fatal: unexpected ai_family\n");
exit(EXIT_FAILURE);
}
connect_req->data = state;
}
void connect_cb(uv_connect_t *req, int status)
{
connect_req_state_t *state = (connect_req_state_t *)req->data;
if (status != 0) {
// Connection failed. Try the next addrinfo.
if (state->ai->ai_next == NULL) {
fprintf(stderr, "connect_cb: fatal: no remaining addrinfos\n");
exit(EXIT_FAILURE);
}
state->ai = state->ai->ai_next;
try_next_addrinfo(state);
} else {
// Connection succeeded. Release the addrinfo list.
uv_freeaddrinfo(state->ai0);
printf("Connection successful!\n");
}
free(req);
}
int main(int argc, const char *argv[])
{
my_loop = uv_default_loop();
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
uv_getaddrinfo_t *gai_handle = calloc(1, sizeof(uv_getaddrinfo_t));
uv_getaddrinfo(my_loop, gai_handle, gai_cb, "w f4f f f f3", "http", &hints);
uv_run(my_loop);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment