Bläddra i källkod

Add code to connect to host given by its hostname.

master
Richard Nyberg 16 år sedan
förälder
incheckning
b4be0683e6
3 ändrade filer med 123 tillägg och 1 borttagningar
  1. +1
    -1
      btpd/Makefile.am
  2. +6
    -0
      btpd/btpd.h
  3. +116
    -0
      btpd/nameconn.c

+ 1
- 1
btpd/Makefile.am Visa fil

@@ -6,7 +6,7 @@ btpd_SOURCES=\
download.c download_subr.c download.h\
http_tr_if.c\
main.c\
net.c net.h net_types.h\
nameconn.c net.c net.h net_types.h\
net_buf.c net_buf.h\
opts.c opts.h\
peer.c peer.h\


+ 6
- 0
btpd/btpd.h Visa fil

@@ -90,4 +90,10 @@ aictx_t btpd_addrinfo(const char *node, short port, struct addrinfo *hints,
void (*cb)(void *, int, struct addrinfo *), void *arg);
void btpd_addrinfo_cancel(aictx_t ctx);


typedef struct nameconn *nameconn_t;
nameconn_t btpd_name_connect(const char *name, short port,
void (*cb)(void *, int, int), void *arg);
void btpd_name_connect_cancel(nameconn_t nc);

#endif

+ 116
- 0
btpd/nameconn.c Visa fil

@@ -0,0 +1,116 @@
#include "btpd.h"

struct nameconn {
struct event write_ev;
void (*cb)(void *, int, int);
void *arg;
aictx_t ai_handle;
struct addrinfo *ai_res, *ai_cur;
int sd;
enum { NC_AI, NC_CONN } state;
};

static void nc_connect(struct nameconn *nc);

static void
nc_free(struct nameconn *nc)
{
if (nc->ai_res != NULL)
freeaddrinfo(nc->ai_res);
free(nc);
}

static void
nc_done(struct nameconn *nc, int error)
{
nc->cb(nc->arg, error, nc->sd);
nc_free(nc);
}

static void
nc_write_cb(int sd, short type, void *arg)
{
struct nameconn *nc = arg;
int error;
socklen_t errsiz = sizeof(int);
if (getsockopt(nc->sd, SOL_SOCKET, SO_ERROR, &error, &errsiz) < 0)
btpd_err("getsockopt error (%s).\n", strerror(errno));
if (error == 0)
nc_done(nc, 0);
else {
close(nc->sd);
nc->ai_cur = nc->ai_cur->ai_next;
nc_connect(nc);
}
}

static void
nc_connect(struct nameconn *nc)
{
struct addrinfo *ai;
int err;

again:
if ((ai = nc->ai_cur) == NULL) {
nc_done(nc, ENOTCONN);
return;
}

if ((nc->sd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0)
btpd_err("Failed to create socket (%s).\n", strerror(errno));

set_nonblocking(nc->sd);

err = connect(nc->sd, ai->ai_addr, ai->ai_addrlen);
if (err == 0)
nc_done(nc, 0);
else if (err < 0 && errno == EINPROGRESS) {
event_set(&nc->write_ev, nc->sd, EV_WRITE, nc_write_cb, nc);
btpd_ev_add(&nc->write_ev, NULL);
} else {
close(nc->sd);
nc->ai_cur = ai->ai_next;
goto again;
}
}

static void
nc_ai_cb(void *arg, int error, struct addrinfo *ai)
{
struct nameconn *nc = arg;
if (error == 0) {
nc->ai_cur = nc->ai_res = ai;
nc->state = NC_CONN;
nc_connect(nc);
} else
nc_done(nc, error);
}

nameconn_t
btpd_name_connect(const char *name, short port, void (*cb)(void *, int, int),
void *arg)
{
struct addrinfo hints;
struct nameconn *nc = btpd_calloc(1, sizeof(*nc));
nc->cb = cb;
nc->arg = arg;
nc->sd = -1;
bzero(&hints, sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
nc->ai_handle = btpd_addrinfo(name, port, &hints, nc_ai_cb, nc);
return nc;
}

void
btpd_name_connect_cancel(struct nameconn *nc)
{
if (nc->state == NC_AI)
btpd_addrinfo_cancel(nc->ai_handle);
else {
btpd_ev_del(&nc->write_ev);
close(nc->sd);
}
nc_free(nc);
}

Laddar…
Avbryt
Spara