src/lib/tcp_server.c
author Tero Marttila <terom@fixme.fi>
Thu, 28 May 2009 01:17:36 +0300
branchnew-lib-errors
changeset 219 cefec18b8268
parent 192 src/tcp_server.c@8cabaf67cc90
permissions -rw-r--r--
some of the lib/transport stuff compiles
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include "tcp_internal.h"
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "sock_internal.h"
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include "log.h"
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <unistd.h>
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
 * Service methods
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
void tcp_server__deinit (service_t *service)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    struct tcp_server *serv = service_check(service, &tcp_server_type);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    14
    tcp_server_deinit(serv);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
 * Service type
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    19
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
const struct service_type tcp_server_type = {
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
    .base_type = {
185
259b5841a0e6 add a crude test_tcp, fix some tcp_server bugs, add missing service_destroy function
Tero Marttila <terom@fixme.fi>
parents: 178
diff changeset
    22
        .parent = &service_type_type,
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    23
    },
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
    .methods = {
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        .deinit = tcp_server__deinit,
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
    },
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    27
};
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
 * We got a new client, build a transport for it and give it to the user
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
static err_t tcp_server_client (struct tcp_server *serv, evutil_socket_t sock, error_t *err)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    34
    struct tcp_transport *trans;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    35
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    36
    // create a new transport for it, this also makes it nonblocking
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    37
    if (tcp_transport_create(&trans, &serv->base_service.info.trans_info, sock, err))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    38
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    39
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    40
    // make it connected
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    41
    // this will call transport_callbacks::on_connect, which is all the user needs
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
    if (tcp_transport_connected(trans, err))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    45
    // ok
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    46
    return SUCCESS;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    47
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
error:
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    // cleanup
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    50
    if (trans)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        tcp_transport_destroy(trans);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    return ERROR_CODE(err);    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
 * Libevent callback
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
static void tcp_server_on_accept (evutil_socket_t sock, short what, void *arg)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    struct tcp_server *serv = arg;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    evutil_socket_t client_sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
    error_t err;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
    (void) what;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
    // accept as a new client connection
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    if ((client_sock = accept(sock, NULL, NULL)) < 0 && errno != EAGAIN)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
        JUMP_SET_ERROR_ERRNO(&err, ERR_ACCEPT);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    71
    // spurious read event?
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
    if (client_sock < 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
        return;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
    // handle it
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
    if (tcp_server_client(serv, client_sock, &err))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    77
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
    // ok
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
    return;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
error:
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    if (client_sock >= 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
        EVUTIL_CLOSESOCKET(client_sock);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
    // faaail
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
    service_error(&serv->base_service, &err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    89
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    90
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    91
 * Attempts to construct a listen()'d socket with the given addr, and return it
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    92
 *
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    93
 * @param addr the addrinfo to try and create a socket for
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
 * @param err returned error info
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
 * @return listening socket, or -err_t on error
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
static int tcp_server_sock_addr (struct addrinfo *addr, error_t *err)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
    evutil_socket_t sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    // create the sock
185
259b5841a0e6 add a crude test_tcp, fix some tcp_server bugs, add missing service_destroy function
Tero Marttila <terom@fixme.fi>
parents: 178
diff changeset
   102
    if ((sock = tcp_sock_create(addr, err)) < 0)
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
    // bind it
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    if (bind(sock, addr->ai_addr, addr->ai_addrlen) < 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
        JUMP_SET_ERROR_ERRNO(err, ERR_BIND);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
    // listen
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
    if (listen(sock, TCP_SERVER_BACKLOG) < 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
        JUMP_SET_ERROR_ERRNO(err, ERR_LISTEN);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
    // ok, valid socket
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    return sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
error:
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    if (sock >= 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   118
        // cleanup
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
        EVUTIL_CLOSESOCKET(sock);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    return -ERROR_CODE(err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
 * Construct a listen()'d socket with the given resolver result, and return it.
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
 *
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
 * @param rr the resolver lookup result to create a socket for
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
 * @param err returned error info
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   129
 * @return listening socket, or -err_t on error
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
static int tcp_server_sock (struct resolve_result *rr, error_t *err)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
    struct addrinfo *addr;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    evutil_socket_t sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
    // try each addrinfo
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
    while ((addr = resolve_result_next(rr))) {
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        // attempt to construct given socket
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        if ((sock = tcp_server_sock_addr(addr, err)) < 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
            // log an informative error warning
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
            log_warn_error(err, "%s", resolve_addr_text(addr)); 
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
        else
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
            // got a valid socket 
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
            break;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
    }
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
    if (sock >= 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
        // valid socket
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
        return sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   151
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
    else
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
        // some error occured
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
        return -ERROR_CODE(err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
err_t tcp_server_listen (struct tcp_server *serv, const char *interface, const char *service, error_t *err)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    struct resolve_result rr;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
    evutil_socket_t sock;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
    // get the global event_base
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
    struct event_base *ev_base = _sock_stream_ctx.ev_base;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
    // init the resolver
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
    resolve_result_init(&rr);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
    // resolve the interface/service
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
    if (resolve_addr(&rr, interface, service, SOCK_STREAM, AI_PASSIVE, err))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
        return ERROR_CODE(err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
    // create the socket
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
    if ((sock = tcp_server_sock(&rr, err)) < 0)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
192
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   176
    // deinit lookup results
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   177
    resolve_result_deinit(&rr);
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   178
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
    // make it nonblocking
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
    if (evutil_make_socket_nonblocking(sock))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        JUMP_SET_ERROR_STR(err, ERR_MISC, "evutil_make_socket_nonblocking");
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
    // construct event for the sock
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
    if ((serv->ev = event_new(ev_base, sock, EV_READ | EV_PERSIST, tcp_server_on_accept, serv)) == NULL)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
        JUMP_SET_ERROR(err, ERR_EVENT_NEW);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
    // add it
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
    if (event_add(serv->ev, NULL))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
        JUMP_SET_ERROR(err, ERR_EVENT_ADD);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
    // ok
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
    return SUCCESS;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
error:
192
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   195
    // deinit results just to be sure
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   196
    resolve_result_deinit(&rr);
8cabaf67cc90 add missing resolve_result_deinit to tcp_server_listen
Tero Marttila <terom@fixme.fi>
parents: 185
diff changeset
   197
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
    if (sock >= 0 && !serv->ev)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
        // need to close socket ourselves, because we couldn't register our event for it
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
        EVUTIL_CLOSESOCKET(sock);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
    // general cleanup
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
    tcp_server_deinit(serv);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
    
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
    return ERROR_CODE(err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
void tcp_server_deinit (struct tcp_server *serv)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
    if (serv->ev) {
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
        // ignore errors
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
        event_del(serv->ev);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
        // ignore errors
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
        close(event_get_fd(serv->ev));
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
        
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
        // release event
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
        event_free(serv->ev);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
        
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   220
        // invalidate
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   221
        serv->ev = NULL;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   222
    }
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   223
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   224
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   225
static void tcp_server_destroy (struct tcp_server *serv)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   226
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   227
    tcp_server_deinit(serv);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   228
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
    free(serv);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
}
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
/*
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
 * Public interface
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
 */
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
err_t tcp_listen (const struct service_info *info, service_t **service_ptr, 
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
        const char *interface, const char *service, error_t *err)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
{
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
    struct tcp_server *serv;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
    // alloc
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    if ((serv = calloc(1, sizeof(*serv))) == NULL)
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
        return SET_ERROR(err, ERR_MEM);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
    // init service
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
    service_init(&serv->base_service, &tcp_server_type, info);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
    // init ourselves
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
    if (tcp_server_listen(serv, interface, service, err))
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
        goto error;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
    // ok
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    *service_ptr = &serv->base_service;
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
185
259b5841a0e6 add a crude test_tcp, fix some tcp_server bugs, add missing service_destroy function
Tero Marttila <terom@fixme.fi>
parents: 178
diff changeset
   254
    return SUCCESS;
259b5841a0e6 add a crude test_tcp, fix some tcp_server bugs, add missing service_destroy function
Tero Marttila <terom@fixme.fi>
parents: 178
diff changeset
   255
178
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
error:
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   257
    tcp_server_destroy(serv);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
    return ERROR_CODE(err);
3d357d055d67 implement tcp_server, along with new error codes
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
}