Created
March 22, 2012 15:11
-
-
Save anonymous/2158903 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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