src/sock_tcp.c
author Tero Marttila <terom@fixme.fi>
Wed, 01 Apr 2009 18:30:47 +0300
changeset 108 50ff7ac8a725
parent 85 75bc8b164ef8
child 109 bfe9b9a8fe5b
permissions -rw-r--r--
implement modules_path + module_load with NULL path
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "sock_tcp.h"
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
     3
#include "log.h"
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <stdlib.h>
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
#include <sys/types.h>
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include <sys/socket.h>
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
#include <unistd.h>
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
     9
#include <fcntl.h>
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
#include <string.h>
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    11
#include <assert.h>
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
/*
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    14
 * Our basic socket event handler for driving our callbacks
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    15
 */
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    16
static void sock_tcp_event_handler (evutil_socket_t fd, short what, void *arg) 
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    17
{
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    18
    struct sock_tcp *sock = arg;
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    19
27
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    20
    (void) fd;
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
    21
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    22
    // invoke appropriate callback
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    23
    sock_stream_invoke_callbacks(SOCK_TCP_BASE(sock), what);
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    24
}
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    25
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    26
/*
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    27
 * Our sock_stream_methods.read method
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
 */
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    29
static err_t sock_tcp_read (struct sock_stream *base_sock, void *buf, size_t *len)
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
{
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
    struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    32
    int ret;
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    33
    
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    34
    // read(), and detect non-EAGAIN or EOF
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    35
    if ((ret = read(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    36
        // unexpected error
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    37
        RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_READ);
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    38
    
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    39
    else if (ret == 0)
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    40
        // EOF
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    41
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_READ_EOF);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    43
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    44
    if (ret < 0) {
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    45
        // EAGAIN -> zero bytes
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    46
        *len = 0;
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    47
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    48
    } else {
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    49
        // normal -> bytes read
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    50
        *len = ret;
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    51
    }
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    52
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    53
    // ok
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    54
    return SUCCESS;
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
}
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
/*
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    58
 * Our sock_stream_methods.write method
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
 */
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    60
static err_t sock_tcp_write (struct sock_stream *base_sock, const void *buf, size_t *len)
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
{
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    63
    int ret;
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    64
    
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    65
    // write(), and detect non-EAGAIN or EOF
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    66
    if ((ret = write(sock->fd, buf, *len)) < 0 && errno != EAGAIN)
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    67
        // unexpected error
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
    68
        RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_WRITE);
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    69
    
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    70
    else if (ret == 0)
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    71
        // EOF
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    72
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_WRITE_EOF);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    74
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    75
    if (ret < 0) {
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    76
        // EAGAIN -> zero bytes
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    77
        *len = 0;
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    78
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    79
    } else {
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    80
        // normal -> bytes read
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    81
        *len = ret;
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
    82
    }
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    83
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    84
    return SUCCESS;
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    85
}
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    86
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    87
static err_t sock_tcp_event_init (struct sock_stream *base_sock)
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    88
{
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    89
    struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    90
    err_t err;
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    91
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    92
    // set nonblocking
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    93
    if ((err = sock_tcp_set_nonblock(sock, 1)))
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    94
        return err;
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    95
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    96
    // add ourselves as the event handler
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    97
    if ((err = sock_tcp_init_ev(sock, &sock_tcp_event_handler, sock)))
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
    98
        return err;
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
    99
    
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   100
    // done
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   101
    return SUCCESS;
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   102
}
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   103
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   104
static err_t sock_tcp_event_enable (struct sock_stream *base_sock, short mask)
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   105
{
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   106
    struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   107
    
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   108
    // implemented in sock_tcp_add_event
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   109
    return sock_tcp_add_event(sock, mask);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
}
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   112
static void sock_tcp_release (struct sock_stream *base_sock)
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   113
{
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   114
    struct sock_tcp *sock = SOCK_FROM_BASE(base_sock, struct sock_tcp);
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   115
    
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   116
    // close and free
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   117
    sock_tcp_close(sock);
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   118
    sock_tcp_free(sock);
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   119
}
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   120
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
/*
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   122
 * Our sock_stream_type
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
 */
40
51678c7eae03 add sock_test module and some basic initial tests
Tero Marttila <terom@fixme.fi>
parents: 30
diff changeset
   124
static struct sock_stream_type sock_tcp_type = {
27
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   125
    .methods                = {
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   126
        .read               = &sock_tcp_read,
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   127
        .write              = &sock_tcp_write,
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   128
        .event_init         = &sock_tcp_event_init,
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   129
        .event_enable       = &sock_tcp_event_enable,
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   130
        .release            = &sock_tcp_release,
27
e6639132bead add irc_conn_callbacks, and delay irc_chan_join until on_registered
Tero Marttila <terom@fixme.fi>
parents: 21
diff changeset
   131
    },
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
};
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   134
err_t sock_tcp_alloc (struct sock_tcp **sock_ptr)
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
{
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    // alloc
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   137
    if ((*sock_ptr = calloc(1, sizeof(**sock_ptr))) == NULL)
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   138
        return ERR_CALLOC;
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   139
    
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   140
    // initialize base with sock_tcp_type
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   141
    sock_stream_init(SOCK_TCP_BASE(*sock_ptr), &sock_tcp_type);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
21
0911d0b828d4 add basic log.c module
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   143
    // invalid fds are <0
0911d0b828d4 add basic log.c module
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   144
    (*sock_ptr)->fd = -1;
0911d0b828d4 add basic log.c module
Tero Marttila <terom@fixme.fi>
parents: 12
diff changeset
   145
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   146
    // done
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   147
    return SUCCESS;
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   148
}
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   149
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   150
err_t sock_tcp_init_fd (struct sock_tcp *sock, int fd)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   151
{
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   152
    // valid fd
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   153
    assert(fd >= 0);
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   154
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
    // initialize
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
    sock->fd = fd;
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
    // done
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   159
    return SUCCESS;
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
}
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   162
err_t sock_tcp_init_ev (struct sock_tcp *sock, void (*ev_cb)(evutil_socket_t, short, void *), void *cb_arg)
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   163
{
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   164
    // require valid fd
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   165
    assert(sock->fd >= 0);
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   166
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   167
    // this is initialization
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   168
    assert(sock->ev_read == NULL && sock->ev_write == NULL);
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   169
    
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   170
    // create new event
11
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   171
    if ((sock->ev_read = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_READ, ev_cb, cb_arg)) == NULL)
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   172
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   173
14e79683c48c working event-based operation for sock_tcp
Tero Marttila <terom@fixme.fi>
parents: 10
diff changeset
   174
    if ((sock->ev_write = event_new(_sock_stream_ctx.ev_base, sock->fd, EV_WRITE, ev_cb, cb_arg)) == NULL)
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   175
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_NEW);
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   176
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   177
    // ok
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   178
    return SUCCESS;
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   179
}
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   180
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   181
void sock_tcp_deinit_ev (struct sock_tcp *sock)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   182
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   183
    if (sock->ev_read) {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   184
        event_del(sock->ev_read);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   185
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   186
        sock->ev_read = NULL;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   187
    }
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   188
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   189
    if (sock->ev_write) {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   190
        event_del(sock->ev_write);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   191
        
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   192
        sock->ev_write = NULL;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   193
    }
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   194
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   195
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   196
err_t sock_tcp_init_socket (struct sock_tcp *sock, struct addrinfo *addr, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   197
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   198
    // must not be set already
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   199
    assert(sock->fd < 0);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   200
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   201
    // call socket
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   202
    if ((sock->fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol)) < 0)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   203
        RETURN_SET_ERROR_ERRNO(err, ERR_SOCKET);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   204
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   205
    // ok
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   206
    return SUCCESS;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   207
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   208
12
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   209
err_t sock_tcp_add_event (struct sock_tcp *sock, short mask)
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   210
{
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   211
    // just add the appropraite events
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   212
    if (mask & EV_READ && event_add(sock->ev_read, NULL))
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   213
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   214
 
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   215
    if (mask & EV_WRITE && event_add(sock->ev_write, NULL))
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   216
        return SET_ERROR(SOCK_TCP_ERR(sock), ERR_EVENT_ADD);
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   217
    
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   218
    // done
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   219
    return SUCCESS;
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   220
}
4147fae232d9 update sock_stream_read/write semantics for EOF/EAGAIN, tentative event-based gnutls code
Tero Marttila <terom@fixme.fi>
parents: 11
diff changeset
   221
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   222
/**
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   223
 * Attempt to connect to the given addrinfo, or the next one, if that fails, etc.
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   224
 */
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   225
static err_t sock_tcp_connect_async_continue (struct sock_tcp *sock, struct addrinfo *addr, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   226
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   227
    // no more addresses left?
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   228
    if (!addr)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   229
        // XXX: rename error
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   230
        return SET_ERROR(err, ERR_GETADDRINFO_EMPTY);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   231
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   232
    // try and connect to each one until we find one that works
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   233
    do {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   234
        // attempt to start connect
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   235
        if (sock_tcp_connect_async_addr(sock, addr, err) == SUCCESS)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   236
            break;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   237
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   238
        // try the next one
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   239
        log_warn("sock_tcp_connect_async_addr(%s): %s", addr->ai_canonname, error_msg(err));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   240
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   241
    } while ((addr = addr->ai_next));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   242
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   243
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   244
    if (addr) {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   245
        // we succesfully did a sock_tcp_connect_async_addr on valid address
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   246
        return SUCCESS;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   247
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   248
    } else {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   249
        // all of the connect_async_addr's failed, return the last error
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   250
        return ERROR_CODE(err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   251
    }
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   252
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   253
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   254
/**
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   255
 * Our async connect operation has completed, clean up addrinfos and events, and call the user callback. The given
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   256
 * \a err should be NULL for successful completion, or the error for unsuccesfully completion.
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   257
 */
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   258
static void sock_tcp_connect_async_done (struct sock_tcp *sock, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   259
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   260
    // free the addrinfo
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   261
    freeaddrinfo(sock->async_res); 
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   262
    sock->async_res = sock->async_cur = NULL;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   263
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   264
    // remove our event handler so the user can install their own
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   265
    sock_tcp_deinit_ev(sock);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   266
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   267
    // ok, run callback
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   268
    SOCK_TCP_BASE(sock)->conn_cb_func(SOCK_TCP_BASE(sock), err, SOCK_TCP_BASE(sock)->conn_cb_arg);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   269
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   270
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   271
/**
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   272
 * Our start_connect callback
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   273
 */
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   274
static void sock_tcp_connect_cb (int fd, short what, void *arg)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   275
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   276
    struct sock_tcp *sock = arg;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   277
    int optval;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   278
    socklen_t optlen;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   279
    struct error_info err;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   280
    err_t tmp;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   281
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   282
    // XXX: timeouts
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   283
    (void) what;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   284
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   285
    // read error code
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   286
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   287
        JUMP_SET_ERROR_ERRNO(&err, ERR_GETSOCKOPT);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   288
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   289
    // sanity-check optlen... not sure if this is sensible
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   290
    if (optlen != sizeof(optval))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   291
        JUMP_SET_ERROR_EXTRA(&err, ERR_GETSOCKOPT, EINVAL);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   292
        
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   293
    // did the connect complete succesfully or not?
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   294
    if (optval)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   295
        JUMP_SET_ERROR_EXTRA(&err, ERR_CONNECT, optval);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   296
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   297
    // done
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   298
    return sock_tcp_connect_async_done(sock, NULL);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   299
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   300
error:
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   301
    // close the socket
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   302
    if ((tmp = sock_tcp_close(sock)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   303
        log_warn("error closing socket after connect error: %s", error_name(tmp));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   304
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   305
    // log a warning
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   306
    log_warn("connect to '%s' failed: %s", sock->async_cur->ai_canonname, error_msg(&err));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   307
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   308
    // try the next one or fail completely
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   309
    if (sock_tcp_connect_async_continue(sock, sock->async_cur->ai_next, &err))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   310
        sock_tcp_connect_async_done(sock, &err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   311
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   312
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   313
err_t sock_tcp_connect_async_addr (struct sock_tcp *sock, struct addrinfo *addr, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   314
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   315
    int ret;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   316
    err_t tmp;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   317
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   318
    // first, create the socket
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   319
    if (sock_tcp_init_socket(sock, addr, err))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   320
        return ERROR_CODE(err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   321
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   322
    // then, set it up as nonblocking
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   323
    if ((ERROR_CODE(err) = sock_tcp_set_nonblock(sock, true)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   324
        goto error;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   325
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   326
    // then, initiate the connect
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   327
    if ((ret = connect(sock->fd, addr->ai_addr, addr->ai_addrlen)) < 0 && errno != EINPROGRESS) 
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   328
        JUMP_SET_ERROR_ERRNO(err, ERR_CONNECT);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   329
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   330
    if (ret < 0) {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   331
        // ok, connect started, setup our completion callback
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   332
        if ((ERROR_CODE(err) = sock_tcp_init_ev(sock, &sock_tcp_connect_cb, sock)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   333
            goto error;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   334
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   335
        // enable for write
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   336
        if ((ERROR_CODE(err) = sock_tcp_add_event(sock, EV_WRITE)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   337
            goto error;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   338
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   339
        // set the "current" address in case it fails and we need to try the next one
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   340
        sock->async_cur = addr;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   341
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   342
    } else {
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   343
        // oops... blocking connect - fail to avoid confusion
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   344
        // XXX: come up with a better error name to use
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   345
        JUMP_SET_ERROR_EXTRA(err, ERR_CONNECT, EINPROGRESS);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   346
    }
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   347
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   348
    // ok
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   349
    return SUCCESS;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   350
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   351
error:
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   352
    // close the stuff we did open
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   353
    if ((tmp = sock_tcp_close(sock)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   354
        log_warn("error closing socket after connect error: %s", error_name(tmp));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   355
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   356
    return ERROR_CODE(err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   357
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   358
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   359
err_t sock_tcp_connect_async_begin (struct sock_tcp *sock, const char *hostname, const char *service, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   360
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   361
    struct addrinfo hints;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   362
    int ret;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   363
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   364
    // hints
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   365
    memset(&hints, 0, sizeof(hints));
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   366
    hints.ai_family = AF_UNSPEC;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   367
    hints.ai_socktype = SOCK_STREAM;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   368
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   369
    // resolve
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   370
    if ((ret = getaddrinfo(hostname, service, &hints, &sock->async_res)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   371
        RETURN_SET_ERROR_EXTRA(err, ERR_GETADDRINFO, ret);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   372
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   373
    // start connecting
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   374
    return sock_tcp_connect_async_continue(sock, sock->async_res, err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   375
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   376
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   377
err_t sock_tcp_connect_blocking (struct sock_tcp *sock, const char *hostname, const char *service, struct error_info *err)
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   378
{
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
    struct addrinfo hints, *res, *r;
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   380
    int ret;
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   381
    
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   382
    // zero error code
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   383
    RESET_ERROR(err);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   384
    
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   385
    // hints
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   386
    memset(&hints, 0, sizeof(hints));
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   387
    hints.ai_family = AF_UNSPEC;
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   388
    hints.ai_socktype = SOCK_STREAM;
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   389
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   390
    // resolve
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   391
    if ((ret = getaddrinfo(hostname, service, &hints, &res)))
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   392
        RETURN_SET_ERROR_EXTRA(err, ERR_GETADDRINFO, ret);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   393
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   394
    // try each result in turn
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   395
    for (r = res; r; r = r->ai_next) {
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   396
        // create the socket
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   397
        if ((sock->fd = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) < 0) {
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   398
            // remember error
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   399
            SET_ERROR_ERRNO(err, ERR_SOCKET);
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   400
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   401
            // skip to next one
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   402
            continue;
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   403
        }
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   404
        
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   405
        // connect to remote address
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   406
        if (connect(sock->fd, r->ai_addr, r->ai_addrlen)) {
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   407
            // remember error
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   408
            SET_ERROR_ERRNO(err, ERR_CONNECT);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   409
            
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   410
            // close/invalidate socket
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   411
            close(sock->fd);
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   412
            sock->fd = -1;
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   413
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   414
            // skip to next one
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   415
            continue;
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   416
        }
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   417
        
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   418
        // valid socket, use this
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   419
        break;
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   420
    }
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   421
    
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   422
    // ensure we got some valid socket, else return last error code
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   423
    if (sock->fd < 0) {
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   424
        // did we hit some error?
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   425
        if (IS_ERROR(err))
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   426
            // return last error
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   427
            return ERROR_CODE(err);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   428
        
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   429
        else
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   430
            // no results
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   431
            return SET_ERROR(err, ERR_GETADDRINFO_EMPTY);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   432
    }
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   433
    
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   434
    // ok, done
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   435
    return 0;    
1
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   436
}
cf0e1bb6bcab a fancy socket abstraction layer, with TCP, next, SSL. Also, .hgignore
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   437
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   438
err_t sock_tcp_set_nonblock (struct sock_tcp *sock, bool nonblock)
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   439
{
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   440
    // fcntl it
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   441
    // XXX: maintain old flags?
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   442
    if (fcntl(sock->fd, F_SETFL, nonblock ? O_NONBLOCK : 0) < 0)
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   443
        RETURN_SET_ERROR_ERRNO(SOCK_TCP_ERR(sock), ERR_FCNTL);
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   444
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   445
    // ok
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   446
    return SUCCESS;
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   447
}
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   448
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   449
err_t sock_tcp_close (struct sock_tcp *sock)
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   450
{
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   451
    struct error_info *err = SOCK_TCP_ERR(sock);
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   452
    
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   453
    // no errors yet
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   454
    RESET_ERROR(err);
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   455
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   456
    // must be connected
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   457
    assert(sock->fd >= 0);
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   458
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   459
    // kill any events
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   460
    sock_tcp_deinit_ev(sock);
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   461
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   462
    // close the socket itself
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   463
    if (close(sock->fd))
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   464
        SET_ERROR_ERRNO(err, ERR_CLOSE);
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   465
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   466
    // invalidate
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   467
    sock->fd = -1;
29
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   468
3f0f2898fea3 add sock_gnutls_destroy, and error cleanup for sock_ssl_connect. Fix various XXX's
Tero Marttila <terom@fixme.fi>
parents: 28
diff changeset
   469
    return ERROR_CODE(err);
28
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   470
}
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   471
9c1050bc8709 add sock_stream_release/line_proto_release/irc_conn_release functions, and add proper cleanup to irc_net_create
Tero Marttila <terom@fixme.fi>
parents: 27
diff changeset
   472
void sock_tcp_free (struct sock_tcp *sock)
10
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   473
{
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   474
    // must not be connected
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   475
    assert(sock->fd < 0);
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   476
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   477
    // free
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   478
    free(sock);
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   479
}
9fe218576d13 fix sock_stream read/write return value, move line buffer inside of line_proto, add some initial code for event-based non-blocking operation
Tero Marttila <terom@fixme.fi>
parents: 8
diff changeset
   480
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   481
err_t sock_tcp_connect (struct sock_stream **sock_ptr, const char *host, const char *service, struct error_info *err)
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   482
{
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   483
    struct sock_tcp *sock;
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   484
    
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   485
    // allocate
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   486
    if ((ERROR_CODE(err) = sock_tcp_alloc(&sock)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   487
        return ERROR_CODE(err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   488
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   489
    // connect    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   490
    if (sock_tcp_connect_blocking(sock, host, service, err))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   491
        goto error;
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   492
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   493
    // good
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   494
    *sock_ptr = SOCK_TCP_BASE(sock);
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   495
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   496
    return 0;
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   497
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   498
error:
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   499
    // cleanup
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   500
    sock_tcp_free(sock);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   501
        
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   502
    // return error code
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   503
    return ERROR_CODE(err);
2
a834f0559939 working SSL using gnutls - a bit of a painful process
Tero Marttila <terom@fixme.fi>
parents: 1
diff changeset
   504
}
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   505
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   506
err_t sock_tcp_connect_async (struct sock_stream **sock_ptr, const char *host, const char *service, 
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   507
        sock_stream_connect_cb cb_func, void *cb_arg, struct error_info *err)
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   508
{
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   509
    struct sock_tcp *sock;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   510
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   511
    // allocate
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   512
    if ((ERROR_CODE(err) = sock_tcp_alloc(&sock)))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   513
        return ERROR_CODE(err);
3
cc94ae754e2a error handling magic
Tero Marttila <terom@fixme.fi>
parents: 2
diff changeset
   514
85
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   515
    // store the callbacks
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   516
    SOCK_TCP_BASE(sock)->conn_cb_func = cb_func;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   517
    SOCK_TCP_BASE(sock)->conn_cb_arg = cb_arg;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   518
    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   519
    // connect    
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   520
    if (sock_tcp_connect_async_begin(sock, host, service, err))
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   521
        goto error;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   522
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   523
    // good
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   524
    *sock_ptr = SOCK_TCP_BASE(sock);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   525
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   526
    return 0;
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   527
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   528
error:
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   529
    // cleanup
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   530
    sock_tcp_free(sock);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   531
        
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   532
    // return error code
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   533
    return ERROR_CODE(err);
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   534
}
75bc8b164ef8 async TCP connects,
Tero Marttila <terom@fixme.fi>
parents: 40
diff changeset
   535