# HG changeset patch # User Tero Marttila # Date 1235279337 -7200 # Node ID a09a0797f6f05648a7a6340dec725cd31d811a95 # Parent a3ca0f97a075dc5b82c79c8e247857d009bdef68 ERROR-ify sock_gnutls diff -r a3ca0f97a075 -r a09a0797f6f0 src/error.h --- a/src/error.h Sun Feb 22 06:52:55 2009 +0200 +++ b/src/error.h Sun Feb 22 07:08:57 2009 +0200 @@ -34,6 +34,10 @@ /* GnuTLS errors */ ERR_GNUTLS_CERT_ALLOC_CRED = 0x010101, ERR_GNUTLS_GLOBAL_INIT = 0x010102, + ERR_GNUTLS_INIT = 0x010103, + ERR_GNUTLS_SET_DEFAULT_PRIORITY = 0x010104, + ERR_GNUTLS_CRED_SET = 0x010105, + ERR_GNUTLS_HANDSHAKE = 0x010106, }; /* @@ -69,13 +73,20 @@ #define _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) (err_info_ptr)->code = (err_code); (err_info_ptr)->extra = (err_extra) #define SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); } while (0) -/* Set error.info.code to err_code, and .extra to errno. XXX: should evaulate to err_code */ +/* Set error_info.code to err_code, and .extra to errno. XXX: should evaulate to err_code */ #define _SET_ERROR_ERRNO(err_info_ptr, err_code) _SET_ERROR_EXTRA(err_info_ptr, err_code, errno); #define SET_ERROR_ERRNO(err_info_ptr, err_code) SET_ERROR_EXTRA(err_info_ptr, err_code, errno); -/* Ss above, but also return err_code from func. XXX: use 'return SET_ERROR...' instead */ -#define RETURN_SET_ERROR(err_info_ptr, err_code) do { _SET_ERROR(err_info_ptr, err_code); return (err_code); } while (0) +/* Set error_info from another error_info. Evaluates to the new error_info */ +#define SET_ERROR_INFO(err_info_ptr, from_ptr) (*err_info_ptr = *from_ptr) + +/* Same as above, but also return err_code from func. XXX: use 'return SET_ERROR...' instead */ +#define RETURN_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); return (err_code); } while (0) #define RETURN_SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra) do { _SET_ERROR_EXTRA(err_info_ptr, err_code, err_extra); return (err_code); } while (0) #define RETURN_SET_ERROR_ERRNO(err_info_ptr, err_code) do { _SET_ERROR_ERRNO(err_info_ptr, err_code); return (err_code); } while (0) +/* Same as above, but also do a 'goto error' */ +#define JUMP_SET_ERROR(err_info_ptr, err_code) do { SET_ERROR(err_info_ptr, err_code); goto error; } while (0) +#define JUMP_SET_ERROR_INFO(err_info_ptr, from_ptr) do { SET_ERROR_INFO(err_info_ptr, from_ptr); goto error; } while (0) + #endif diff -r a3ca0f97a075 -r a09a0797f6f0 src/nexus.c --- a/src/nexus.c Sun Feb 22 06:52:55 2009 +0200 +++ b/src/nexus.c Sun Feb 22 07:08:57 2009 +0200 @@ -11,7 +11,7 @@ #include "sock.h" #define CONNECT_HOST "irc.fixme.fi" -#define CONNECT_SERV "6697" +#define CONNECT_SERV "6667" #define LINE_LENGTH 512 struct recvline_state { @@ -118,7 +118,9 @@ memset(&recvline_ctx, 0, sizeof(recvline_ctx)); // over-simplified connect - sock = sock_ssl_connect(CONNECT_HOST, CONNECT_SERV); + if (sock_gnutls_connect(&sock, CONNECT_HOST, CONNECT_SERV, &err)) + // XXX: + errx(1, "sock_gnutls_connect"); // read lines and dump them out do { diff -r a3ca0f97a075 -r a09a0797f6f0 src/sock.c --- a/src/sock.c Sun Feb 22 06:52:55 2009 +0200 +++ b/src/sock.c Sun Feb 22 07:08:57 2009 +0200 @@ -7,7 +7,7 @@ err_t sock_init (struct error_info *err) { // XXX: just call these all directly for now - if (sock_gnutls_init(err)) + if (sock_gnutls_global_init(err)) return ERROR_CODE(err); // done diff -r a3ca0f97a075 -r a09a0797f6f0 src/sock.h --- a/src/sock.h Sun Feb 22 06:52:55 2009 +0200 +++ b/src/sock.h Sun Feb 22 07:08:57 2009 +0200 @@ -19,7 +19,7 @@ /* * A simple blocking TCP connect to the given host/service, using getaddrinfo. The connected socket is returned via - * *sock_ptr. In case of errors, additional error information is stored in *err + * *sock_ptr. In case of errors, additional error information is stored in *err. * * @return zero on success, nonzero on error * @@ -28,15 +28,13 @@ err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err); /* - * A simple blocking SSL connect to the given host/service. + * A simple blocking SSL connect to the given host/service. The connected/handshake'd SSL socket is returned via + * *sock_ptr. In case of errors, additional error information is stored in *err. * * XXX: blocking * XXX: doesn't do any certificate verification. - * XXX: exits on error - * - * Returns the socket handle, or NULL on errors. */ -struct sock_stream *sock_ssl_connect (const char *host, const char *service); +err_t sock_gnutls_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err); /* * The generic read/write API for stream sockets. diff -r a3ca0f97a075 -r a09a0797f6f0 src/sock_gnutls.c --- a/src/sock_gnutls.c Sun Feb 22 06:52:55 2009 +0200 +++ b/src/sock_gnutls.c Sun Feb 22 07:08:57 2009 +0200 @@ -54,7 +54,7 @@ return SUCCESS; } -err_t sock_gnutls_init (struct error_info *err) +err_t sock_gnutls_global_init (struct error_info *err) { // global init if ((ERROR_EXTRA(err) = gnutls_global_init()) < 0) @@ -69,41 +69,49 @@ } -// XXX: errors -struct sock_stream *sock_ssl_connect (const char *host, const char *service) +err_t sock_gnutls_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err) { - int _err; - struct sock_gnutls *sock; + struct sock_gnutls *sock = NULL; struct sock_gnutls_client_ctx *ctx = &_sock_gnutls_client_ctx; // alloc if ((sock = calloc(1, sizeof(*sock))) == NULL) - errx(1, "calloc"); + return SET_ERROR(err, ERR_CALLOC); - // initialize - sock->base_tcp.base.type = &sock_gnutls_type; + // initialize base + sock_stream_init(SOCK_GNUTLS_BASE(sock), &sock_gnutls_type); // initialize client session - if ((_err = gnutls_init(&sock->session, GNUTLS_CLIENT)) < 0) - errx(1, "gnutls_init: %s", gnutls_strerror(_err)); + if ((ERROR_EXTRA(err) = gnutls_init(&sock->session, GNUTLS_CLIENT)) < 0) + JUMP_SET_ERROR(err, ERR_GNUTLS_INIT); // ...default priority stuff - gnutls_set_default_priority(sock->session); + if ((ERROR_EXTRA(err) = gnutls_set_default_priority(sock->session))) + JUMP_SET_ERROR(err, ERR_GNUTLS_SET_DEFAULT_PRIORITY); // bind anon credentials - gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, ctx->xcred); + if ((ERROR_EXTRA(err) = gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, ctx->xcred))) + JUMP_SET_ERROR(err, ERR_GNUTLS_CRED_SET); // TCP connect - sock_tcp_init_connect(SOCK_GNUTLS_TCP(sock), host, service); + if (sock_tcp_init_connect(SOCK_GNUTLS_TCP(sock), host, service)) + JUMP_SET_ERROR_INFO(err, SOCK_GNUTLS_ERR(sock)); // bind default transport functions (recv/send) to use the TCP fd gnutls_transport_set_ptr(sock->session, (gnutls_transport_ptr_t) sock->base_tcp.fd); // perform the handshake - if ((_err = gnutls_handshake(sock->session)) < 0) - _sock_gnutls_error(sock, "gnutls_handshake", _err); + if ((ERROR_EXTRA(err) = gnutls_handshake(sock->session)) < 0) + JUMP_SET_ERROR(err, ERR_GNUTLS_HANDSHAKE); // done - return SOCK_GNUTLS_BASE(sock); + *sock_ptr = SOCK_GNUTLS_BASE(sock); + + return SUCCESS; + +error: + // XXX: cleanup + + return ERROR_CODE(err); } diff -r a3ca0f97a075 -r a09a0797f6f0 src/sock_gnutls.h --- a/src/sock_gnutls.h Sun Feb 22 06:52:55 2009 +0200 +++ b/src/sock_gnutls.h Sun Feb 22 07:08:57 2009 +0200 @@ -40,6 +40,6 @@ /* * Initialize the global gnutls state */ -err_t sock_gnutls_init (struct error_info *err); +err_t sock_gnutls_global_init (struct error_info *err); #endif /* SOCK_GNUTLS_H */