From e981fbcf3909fbaba462c7b578f29fa67b3bc74b Mon Sep 17 00:00:00 2001 From: Linus Nordberg Date: Tue, 28 Sep 2010 22:27:04 +0200 Subject: [PATCH] WIP. --- lib/Makefile | 9 +++-- lib/attr.c | 46 ++++++++++++--------- lib/debug.c | 8 ++++ lib/debug.h | 68 +------------------------------ lib/err.c | 84 ++++++++++++++++++++++++++++++--------- lib/examples/Makefile | 4 +- lib/examples/client.c | 46 ++++++++++++++------- lib/libradsec-impl.h | 29 +++++++++----- lib/libradsec.h | 37 ++++++++++------- lib/packet.c | 39 ++++++++++++------ lib/radsec.c | 108 +++++++++++++++++++++++++++++++++++++++++--------- 11 files changed, 300 insertions(+), 178 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index bc35e88..8c6d5b4 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,9 +1,12 @@ CFLAGS = -Wall -g -DDEBUG -OFILES = radsec.o err.o packet.o attr.o -all: libradsec.a +OFILES = attr.o \ + debug.o \ + err.o \ + packet.o \ + radsec.o -base.o: base.c libradsec-base.h libradsec.h ../tlv11.h +all: libradsec.a libradsec.a: $(OFILES) ar rc $@ $^ diff --git a/lib/attr.c b/lib/attr.c index bf5e105..4bd44f7 100644 --- a/lib/attr.c +++ b/lib/attr.c @@ -2,27 +2,35 @@ #include "libradsec.h" #include "libradsec-impl.h" -fixme -attr_create(fixme) +int +rs_attr_create(struct rs_connection *conn, struct rs_attr **attr, const char *type, const char *val) { + VALUE_PAIR *vp; + struct rs_attr *a; - printf ("creating value pairs\n"); - /* User-Name. */ - vp = pairmake ("User-Name", USER_NAME, 0); - if (!vp) { - fr_perror ("pairmake"); - return -1; - } + *attr = NULL; + a = (struct rs_attr *) malloc (sizeof(struct rs_attr)); + if (!a) + return rs_conn_err_push_fl (conn, RSE_NOMEM, __FILE__, __LINE__, NULL); + memset (a, 0, sizeof(struct rs_attr)); - /* User-Password. */ - { - size_t pwlen = sizeof(USER_PW); - strncpy (user_pw, USER_PW, sizeof(user_pw)); - rad_pwencode(user_pw, &pwlen, SECRET, reqauth); - } - pairadd (&vp, pairmake ("User-Password", user_pw, 0)); - pkt->vps = vp; + vp = pairmake (type, val, T_OP_EQ); + if (!vp) + { + rs_attr_destroy (a); + return rs_conn_err_push_fl (conn, RSE_FR, __FILE__, __LINE__, + "pairmake: %s", fr_strerror()); + } - printf ("attributes:\n"); - vp_printlist (stdout, vp); + a->vp = vp; + *attr = a; + return RSE_OK; +} + +void +rs_attr_destroy (struct rs_attr *attr) +{ + if (attr->vp) + pairfree (&attr->vp); + free (attr); } diff --git a/lib/debug.c b/lib/debug.c index 2d4e242..34f4885 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -1,4 +1,6 @@ +#include #include +#include "libradsec.h" #include "libradsec-impl.h" #include "debug.h" @@ -69,3 +71,9 @@ rs_dump_packet (const struct rs_packet *pkt) { print_hex (pkt->rpkt); } + +void +rs_dump_attr (const struct rs_attr *attr) +{ + vp_printlist (stderr, attr->vp); +} diff --git a/lib/debug.h b/lib/debug.h index 83c3650..a541555 100644 --- a/lib/debug.h +++ b/lib/debug.h @@ -5,69 +5,5 @@ if (i % 16 == 0) printf ("\n"); } \ printf ("\n"); } -/* From freeradius-server/src/lib/radius.c */ -#include -static void print_hex(RADIUS_PACKET *packet) -{ - int i; - - if (!packet->data) return; - - printf(" Code:\t\t%u\n", packet->data[0]); - printf(" Id:\t\t%u\n", packet->data[1]); - printf(" Length:\t%u\n", ((packet->data[2] << 8) | - (packet->data[3]))); - printf(" Vector:\t"); - for (i = 4; i < 20; i++) { - printf("%02x", packet->data[i]); - } - printf("\n"); - - if (packet->data_len > 20) { - int total; - const uint8_t *ptr; - printf(" Data:"); - - total = packet->data_len - 20; - ptr = packet->data + 20; - - while (total > 0) { - int attrlen; - - printf("\t\t"); - if (total < 2) { /* too short */ - printf("%02x\n", *ptr); - break; - } - - if (ptr[1] > total) { /* too long */ - for (i = 0; i < total; i++) { - printf("%02x ", ptr[i]); - } - break; - } - - printf("%02x %02x ", ptr[0], ptr[1]); - attrlen = ptr[1] - 2; - ptr += 2; - total -= 2; - - for (i = 0; i < attrlen; i++) { - if ((i > 0) && ((i & 0x0f) == 0x00)) - printf("\t\t\t"); - printf("%02x ", ptr[i]); - if ((i & 0x0f) == 0x0f) printf("\n"); - } - - if ((attrlen & 0x0f) != 0x00) printf("\n"); - - ptr += attrlen; - total -= attrlen; - } - } - fflush(stdout); -} - -/* Local Variables: */ -/* c-file-style: "stroustrup" */ -/* End: */ +void rs_dump_packet (const struct rs_packet *pkt); +void rs_dump_attr (const struct rs_attr *attr); diff --git a/lib/err.c b/lib/err.c index 66c5d94..9fcad0b 100644 --- a/lib/err.c +++ b/lib/err.c @@ -1,3 +1,4 @@ +#include #include #include "libradsec.h" #include "libradsec-impl.h" @@ -8,8 +9,8 @@ const char *_errtxt[] = { "NYI -- not yet implemented", /* 2 RSE_NOSYS */ "invalid handle" /* 3 RSE_INVALID_CTX */ "invalid connection" /* 4 RSE_INVALID_CONN */ - "ERR 5" /* RSE_ */ - "ERR 6" /* RSE_ */ + "connection type mismatch" /* 5 RSE_CONN_TYPE_MISMATCH */ + "FreeRadius error" /* 6 RSE_FR */ "ERR 7" /* RSE_ */ "ERR 8" /* RSE_ */ "ERR 9" /* RSE_ */ @@ -28,27 +29,33 @@ const char *_errtxt[] = { }; static struct rs_error * -_err_new (unsigned int code, const char *msg) +_err_new (unsigned int code, const char *file, int line, const char *fmt, va_list args) { struct rs_error *err; - err = malloc (sizeof (struct rs_error)); + err = malloc (sizeof(struct rs_error)); if (err) { - memset (err, 0, sizeof (struct rs_error)); + int n; + memset (err, 0, sizeof(struct rs_error)); err->code = code; - snprintf (err->buf, sizeof (err->buf), "%s: %s", - code < sizeof (_errtxt) / sizeof (*_errtxt) ? - _errtxt[code] : "invalid error index", - msg); + n = vsnprintf (err->buf, sizeof(err->buf), fmt, args); + if (n > 0) + { + char *sep = strrchr (file, '/'); + if (sep) + file = sep + 1; + snprintf (err->buf + n, sizeof(err->buf) - n, " (%s: %d)", file, + line); + } } return err; } -int -rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg) +static int +_ctx_err_vpush_fl (struct rs_handle *ctx, int code, const char *file, int line, const char *fmt, va_list args) { - struct rs_error *err = _err_new (code, msg); + struct rs_error *err = _err_new (code, file, line, fmt, args); if (err) ctx->err = err; @@ -56,15 +63,45 @@ rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg) } int -rs_conn_err_push (struct rs_connection *conn, int code, const char *msg) +rs_ctx_err_push (struct rs_handle *ctx, int code, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + _ctx_err_vpush_fl (ctx, code, NULL, 0, fmt, args); + va_end (args); + return code; +} + +static int +_conn_err_vpush_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, va_list args) { - struct rs_error *err = _err_new (code, msg); + struct rs_error *err = _err_new (code, file, line, fmt, args); if (err) conn->err = err; return code; } +int +rs_conn_err_push (struct rs_connection *conn, int code, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + _conn_err_vpush_fl (conn, code, NULL, 0, fmt, args); + va_end (args); + return code; +} + +int +rs_conn_err_push_fl (struct rs_connection *conn, int code, const char *file, int line, const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + _conn_err_vpush_fl (conn, code, file, line, fmt, args); + va_end (args); + return code; +} + struct rs_error * rs_ctx_err_pop (struct rs_handle *ctx) { @@ -99,23 +136,32 @@ rs_err_free (struct rs_error *err) } char * -rs_err_msg (struct rs_error *err) +rs_err_msg (struct rs_error *err, int dofree_flag) { char *msg; + if (!err) + return NULL; if (err->msg) msg = err->msg; else msg = strdup (err->buf); - rs_err_free (err); + if (dofree_flag) + rs_err_free (err); return msg; } int -rs_err_code (struct rs_error *err) +rs_err_code (struct rs_error *err, int dofree_flag) { - int code = err->code; - rs_err_free(err); + int code; + + if (!err) + return -1; + code = err->code; + + if (dofree_flag) + rs_err_free(err); return code; } diff --git a/lib/examples/Makefile b/lib/examples/Makefile index e07a32b..ceb97f1 100644 --- a/lib/examples/Makefile +++ b/lib/examples/Makefile @@ -1,12 +1,12 @@ CFLAGS = -Wall -g -all: blocking.o +all: client blocking.o: blocking.c blocking.h ../libradsec-base.h ../libradsec.h $(CC) $(CFLAGS) -c -I .. $^ client: client.c ../libradsec.a ../libradsec.h ../libradsec-impl.h - $(CC) $(CFLAGS) -o $@ -L /usr/lib/freeradius -lfreeradius-radius $^ + $(CC) $(CFLAGS) -o $@ $< -L /usr/lib/freeradius -lfreeradius-radius -L .. -lradsec clean: -rm *.o diff --git a/lib/examples/client.c b/lib/examples/client.c index 37601b6..eab4390 100644 --- a/lib/examples/client.c +++ b/lib/examples/client.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "../libradsec.h" #include "../debug.h" @@ -10,37 +11,54 @@ #define USER_NAME "bob" #define USER_PW "hemligt" -int +struct rs_error * rsx_client (const char *srvname, int srvport) { - struct rs_context *h; - struct rs_connecion *conn; - struct rs_packet *req, *resp; + struct rs_handle *h; + struct rs_connection *conn; + struct rs_peer *server; + struct rs_packet *req; + //struct rs_packet *resp; if (rs_context_create (&h, "/usr/share/freeradius/dictionary")) - return rs_err_code (rs_ctx_err_code (h)); + return NULL; - if (rs_conn_new (h, &conn)) - return rs_err_code (rs_conn_err_code (conn)); - if (rs_conn_add_server (conn, RS_CONN_TYPE_UDP, srvname, srvport, 10, 3, SECRET)) - return rs_err_code (rs_conn_err_code (conn)); + if (rs_conn_create (h, &conn)) + return rs_conn_err_pop (conn); + if (rs_conn_add_server (conn, &server, RS_CONN_TYPE_UDP, srvname, srvport)) + return rs_conn_err_pop (conn); + rs_server_set_timeout (server, 10); + rs_server_set_tries (server, 3); + rs_server_set_secret (server, SECRET); if (rs_packet_create_acc_request (conn, &req, USER_NAME, USER_PW)) - return rs_err_code (rs_conn_err_code (conn)); + return rs_conn_err_pop (conn); - if (rs_packet_send (req)) - return rs_err_code (rs_conn_err_code (conn)); + if (rs_packet_send (conn, req, NULL)) + return rs_conn_err_pop (conn); req = NULL; +#if 0 + printf ("waiting for response\n"); if (rs_packet_recv (conn, &resp)) - return rs_err_code (rs_conn_err_code (conn)); + return rs_conn_err_pop (conn); + printf ("got response\n"); + rs_dump_packet (resp); +#endif rs_conn_destroy (conn); rs_context_destroy (h); + return 0; } int main (int argc, char *argv[]) { - exit (rsx_client ()); + struct rs_error *err; + + err = rsx_client (strsep (argv + 1, ":"), atoi (argv[1])); + if (!err) + return -1; + fprintf (stderr, "%s\n", rs_err_msg (err, 0)); + return rs_err_code (err, 1); } diff --git a/lib/libradsec-impl.h b/lib/libradsec-impl.h index e9ec644..170e90c 100644 --- a/lib/libradsec-impl.h +++ b/lib/libradsec-impl.h @@ -15,6 +15,8 @@ enum rs_cred_type { }; typedef unsigned int rs_cred_type_t; +struct rs_packet; + struct rs_credentials { enum rs_cred_type type; char *identity; @@ -65,19 +67,22 @@ struct rs_handle { }; struct rs_peer { - struct addrinfo addr; + struct rs_connection *conn; + struct addrinfo *addr; char *secret; int timeout; /* client only */ int tries; /* client only */ + struct rs_peer *next; }; struct rs_connection { struct rs_handle *ctx; - enum rs_conn_type conn_type; + enum rs_conn_type type; struct rs_credentials transport_credentials; struct rs_conn_callbacks callbacks; + struct rs_peer peers; + struct rs_peer *active_peer; struct rs_error *err; - struct rs_peer *peer; }; struct rs_packet { @@ -90,16 +95,18 @@ struct rs_attr { VALUE_PAIR *vp; }; +/* Internal functions. */ +int rs_conn_open(struct rs_connection *conn); /* Convenience macros. */ -#define rs_calloc(ctx, nmemb, size) \ - (ctx->alloc_scheme.calloc ? ctx->alloc_scheme.calloc : calloc)(nmemb, size) -#define rs_malloc(ctx, size) \ - (ctx->alloc_scheme.malloc ? ctx->alloc_scheme.malloc : malloc)(size) -#define rs_free(ctx, ptr) \ - (ctx->alloc_scheme.free ? ctx->alloc_scheme.free : free)(ptr) -#define rs_(ctx, realloc, ptr, size) \ - (ctx->alloc_scheme.realloc ? ctx->alloc_scheme.realloc : realloc)(ptr, size) +#define rs_calloc(h, nmemb, size) \ + (h->alloc_scheme.calloc ? h->alloc_scheme.calloc : calloc)(nmemb, size) +#define rs_malloc(h, size) \ + (h->alloc_scheme.malloc ? h->alloc_scheme.malloc : malloc)(size) +#define rs_free(h, ptr) \ + (h->alloc_scheme.free ? h->alloc_scheme.free : free)(ptr) +#define rs_realloc(h, realloc, ptr, size) \ + (h->alloc_scheme.realloc ? h->alloc_scheme.realloc : realloc)(ptr, size) /* Local Variables: */ /* c-file-style: "stroustrup" */ diff --git a/lib/libradsec.h b/lib/libradsec.h index 629e7e1..f956f45 100644 --- a/lib/libradsec.h +++ b/lib/libradsec.h @@ -10,11 +10,14 @@ enum rs_err_code { RSE_NOSYS = 2, RSE_INVALID_CTX = 3, RSE_INVALID_CONN = 4, - RSE_SOME_ERROR = 21 + RSE_CONN_TYPE_MISMATCH = 5, + RSE_FR = 6, + RSE_SOME_ERROR = 21, }; enum rs_conn_type { - RS_CONN_TYPE_UDP = 0, + RS_CONN_TYPE_NONE = 0, + RS_CONN_TYPE_UDP, RS_CONN_TYPE_TCP, RS_CONN_TYPE_TLS, RS_CONN_TYPE_DTLS, @@ -31,6 +34,7 @@ struct rs_packet; /* radsec-impl.h */ struct rs_conn; /* radsec-impl.h */ struct rs_attr; /* radsec-impl.h */ struct rs_error; /* radsec-impl.h */ +struct rs_peer; /* radsec-impl.h */ struct event_base; /* */ /* Function prototypes. */ @@ -39,37 +43,42 @@ void rs_context_destroy(struct rs_handle *ctx); int rs_context_set_alloc_scheme(struct rs_handle *ctx, struct rs_alloc_scheme *scheme); int rs_context_config_read(struct rs_handle *ctx, const char *config_file); -int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn); -int rs_conn_add_server(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port, int timeout, int tries, const char *secret); -int rs_conn_add_listener(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port, const char *secret); +int rs_conn_create(struct rs_handle *ctx, struct rs_connection **conn); +int rs_conn_add_server(struct rs_connection *conn, struct rs_peer **server, rs_conn_type_t type, const char *host, int port); +int rs_conn_add_listener(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port); int rs_conn_destroy(struct rs_connection *conn); int rs_conn_set_eventbase(struct rs_connection *conn, struct event_base *eb); int rs_conn_set_callbacks(struct rs_connection *conn, struct rs_conn_callbacks *cb); -int rs_conn_set_server(struct rs_connection *conn, const char *name); -int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_t buflen); /* NAME <-- most recent server we spoke to */ +int rs_conn_select_server(struct rs_connection *conn, const char *name); +int rs_conn_get_current_server(const struct rs_connection *conn, const char *name, size_t buflen); + +void rs_server_set_timeout(struct rs_peer *server, int timeout); +void rs_server_set_tries(struct rs_peer *server, int tries); +int rs_server_set_secret(struct rs_peer *server, const char *secret); int rs_packet_create_acc_request(struct rs_connection *conn, struct rs_packet **pkt, const char *user_name, const char *user_pw); //int rs_packet_create_acc_accept(cstruct rs_connection *conn, struct rs_packet **pkt); //int rs_packet_create_acc_reject(struct rs_connection *conn, struct rs_packet **pkt); //int rs_packet_create_acc_challenge(struct rs_connection *conn, struct rs_packet **pkt); void rs_packet_destroy(struct rs_packet *pkt); -int rs_packet_add_attr(struct rs_packet *pkt, const struct rs_attr *attr); +void rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr); //int rs_packet_add_new_attr(struct rs_packet *pkt, const char *attr_name, const char *attr_val); int rs_attr_create(struct rs_connection *conn, struct rs_attr **attr, const char *type, const char *val); void rs_attr_destroy(struct rs_attr *attr); -int rs_packet_send(struct rs_conn *conn, const struct rs_packet *pkt, void *user_data); -int rs_packet_receive(struct rs_conn *conn, struct rs_packet **pkt); +int rs_packet_send(struct rs_connection *conn, const struct rs_packet *pkt, void *user_data); +int rs_packet_recv(struct rs_connection *conn, struct rs_packet **pkt); -int rs_ctx_err_push (struct rs_handle *ctx, int code, const char *msg); -int rs_conn_err_push (struct rs_connection *conn, int code, const char *msg); +int rs_ctx_err_push (struct rs_handle *ctx, int code, const char *fmt, ...); +int rs_conn_err_push (struct rs_connection *conn, int code, const char *fmt, ...); +int rs_conn_err_push_fl(struct rs_connection *conn, int code, const char *file, int line, const char *fmt, ...); struct rs_error *rs_ctx_err_pop (struct rs_handle *ctx); struct rs_error *rs_conn_err_pop (struct rs_connection *conn); void rs_err_free (struct rs_error *err); -char *rs_err_msg (struct rs_error *err); -int rs_err_code (struct rs_error *err); +char *rs_err_msg (struct rs_error *err, int dofree_flag); +int rs_err_code (struct rs_error *err, int dofree_flag); /* Local Variables: */ /* c-file-style: "stroustrup" */ diff --git a/lib/packet.c b/lib/packet.c index e734452..68adf2b 100644 --- a/lib/packet.c +++ b/lib/packet.c @@ -1,8 +1,11 @@ #include +#include #include #include "libradsec.h" #include "libradsec-impl.h" - +#if defined DEBUG +#include "debug.h" +#endif int _packet_create (struct rs_connection *conn, struct rs_packet **pkt_out, @@ -45,33 +48,45 @@ rs_packet_create_acc_request (struct rs_connection *conn, if (rs_attr_create (conn, &attr, "User-Name", user_name)) return -1; - if (rs_packet_add_attr (pkt, attr)) - return -1; + rs_packet_add_attr (pkt, attr); if (rs_attr_create (conn, &attr, "User-Password", user_name)) return -1; - if (rs_packet_add_attr (pkt, attr)) - return -1; + /* FIXME: need this too? rad_pwencode(user_pw, &pwlen, SECRET, reqauth) */ + rs_packet_add_attr (pkt, attr); return RSE_OK; } int -rs_packet_send (struct rs_conn *conn, const struct rs_packet *pkt, +rs_packet_send (struct rs_connection *conn, const struct rs_packet *pkt, void *user_data) { - rad_encode (pkt->rpkt, NULL, pkt->conn->secret); + assert (pkt->rpkt); + + if (!conn->active_peer) + { + int err = rs_conn_open (conn); + if (err) + return err; + } + rad_encode (pkt->rpkt, NULL, conn->active_peer->secret); #if defined (DEBUG) - fprintf (stderr, "%s: about to send this to %" - print_hex (pkt); + fprintf (stderr, "%s: about to send this to %s", __func__, "fixme"); + rs_dump_packet (pkt); #endif - - return RSE_NOSYS; } -int rs_packet_receive(struct rs_conn *conn, struct rs_packet **pkt) +int rs_packet_receive(struct rs_connection *conn, struct rs_packet **pkt) { return RSE_NOSYS; } + +void +rs_packet_add_attr(struct rs_packet *pkt, struct rs_attr *attr) +{ + pairadd (&pkt->rpkt->vps, attr->vp); + attr->pkt = pkt; +} diff --git a/lib/radsec.c b/lib/radsec.c index f645ee1..e0c881a 100644 --- a/lib/radsec.c +++ b/lib/radsec.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -12,40 +13,49 @@ rs_context_create(struct rs_handle **ctx, const char *dict) { struct rs_handle *h; - *ctx = NULL; - h = (struct rs_handle *) malloc (sizeof (struct rs_handle)); + if (ctx) + *ctx = NULL; + h = (struct rs_handle *) malloc (sizeof(struct rs_handle)); if (h) { - char *buf; + char *buf1 = NULL, *buf2 = NULL; char *dir, *fn; - buf = malloc (strlen (dict) + 1); - if (!buf) + buf1 = malloc (strlen (dict) + 1); + buf2 = malloc (strlen (dict) + 1); + if (!buf1 || !buf2) { free (h); + if (buf1) + free (buf1); + if (buf2) + free (buf2); return RSE_NOMEM; } - strcpy (buf, dict); - dir = dirname (buf); - free (buf); - strcpy (buf, dict); - fn = basename (buf); - free (buf); + strcpy (buf1, dict); + dir = dirname (buf1); + strcpy (buf2, dict); + fn = basename (buf2); if (dict_init (dir, fn) < 0) { free (h); return RSE_SOME_ERROR; } + free (buf1); + free (buf2); #if defined (DEBUG) fr_log_fp = stderr; fr_debug_flag = 1; #endif + + memset (h, 0, sizeof(struct rs_handle)); fr_randinit (&h->fr_randctx, 0); fr_rand_seed (NULL, 0); - *ctx = h; + if (ctx) + *ctx = h; } - return (h ? RSE_OK : RSE_NOMEM); + return h ? RSE_OK : RSE_NOMEM; } void rs_context_destroy(struct rs_handle *ctx) @@ -63,17 +73,73 @@ int rs_context_config_read(struct rs_handle *ctx, const char *config_file) return RSE_NOSYS; } -int rs_conn_create(const struct rs_handle *ctx, struct rs_connection **conn) +int rs_conn_create(struct rs_handle *ctx, struct rs_connection **conn) { - return RSE_NOSYS; + struct rs_connection *c; + + c = (struct rs_connection *) malloc (sizeof(struct rs_connection)); + if (c) + { + memset (c, 0, sizeof(struct rs_connection)); + c->ctx = ctx; + c->peers.next = &c->peers; + } + if (conn) + *conn = c; + return c ? RSE_OK : rs_ctx_err_push (ctx, RSE_NOMEM, NULL); } -int rs_conn_add_server(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port, int timeout, int tries, const char *secret) +struct addrinfo * +_resolv (const char *host, int port) { - return RSE_NOSYS; + return NULL; } -int rs_conn_add_listener(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port, const char *secret) +int rs_conn_add_server(struct rs_connection *conn, struct rs_peer **server, rs_conn_type_t type, const char *host, int port) +{ + struct rs_peer *srv; + + if (conn->type == RS_CONN_TYPE_NONE) + conn->type = type; + else if (conn->type != type) + return rs_conn_err_push (conn, RSE_CONN_TYPE_MISMATCH, NULL); + + srv = (struct rs_peer *) malloc (sizeof(struct rs_peer)); + if (srv) + { + memset (srv, 0, sizeof(struct rs_peer)); + srv->conn = conn; + srv->addr = _resolv (host, port); + srv->timeout = 10; + srv->tries = 3; + srv->next = conn->peers.next; + conn->peers.next = srv; + } + if (*server) + *server = srv; + return srv ? RSE_OK : rs_conn_err_push (conn, RSE_NOMEM, NULL); +} + +void rs_server_set_timeout(struct rs_peer *server, int timeout) +{ + server->timeout = timeout; +} +void rs_server_set_tries(struct rs_peer *server, int tries) +{ + server->tries = tries; +} +int rs_server_set_secret(struct rs_peer *server, const char *secret) +{ + if (server->secret) + free (server->secret); + server->secret = (char *) malloc (strlen(secret) + 1); + if (!server->secret) + return rs_conn_err_push (server->conn, RSE_NOMEM, NULL); + strcpy (server->secret, secret); + return RSE_OK; +} + +int rs_conn_add_listener(struct rs_connection *conn, rs_conn_type_t type, const char *host, int port) { return RSE_NOSYS; } @@ -102,3 +168,9 @@ int rs_conn_get_server(const struct rs_connection *conn, const char *name, size_ { return RSE_NOSYS; } + +int rs_conn_open(struct rs_connection *conn) +{ + return rs_conn_err_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__, + "%s: NYI", __func__); +} -- 2.1.4