Пример #1
0
int flom_handle_set_unicast_address(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_unicast_address: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_unicast_address(handle->config)),
                STRORNULL(value)));
    switch (handle->state) {
        case FLOM_HANDLE_STATE_INIT:
        case FLOM_HANDLE_STATE_DISCONNECTED:
            flom_config_set_unicast_address(handle->config,
                                            (const gchar *)value);
            /* reset socket name and multicast address*/
            if (NULL != value) {
                flom_handle_set_socket_name(handle, NULL);
                flom_handle_set_multicast_address(handle, NULL);
            } /* if (NULL != value) */
            break;
        default:
            FLOM_TRACE(("flom_handle_set_unicast_address: state %d " \
                        "is not compatible with set operation\n",
                        handle->state));
            return FLOM_RC_API_IMMUTABLE_HANDLE;
    } /* switch (handle->state) */
    return FLOM_RC_OK;
}
Пример #2
0
void flom_handle_set_unicast_address(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_unicast_address: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_unicast_address(handle->config)),
                STRORNULL(value)));
    flom_config_set_unicast_address(handle->config, (const gchar *)value);
    /* reset socket name and multicast address*/
    if (NULL != value) {
        flom_handle_set_socket_name(handle, NULL);
        flom_handle_set_multicast_address(handle, NULL);
    } /* if (NULL != value) */
}
Пример #3
0
int flom_tcp_listen(flom_tcp_t *obj)
{
    enum Exception { GETADDRINFO_ERROR
                     , BIND_ERROR
                     , LISTEN_ERROR
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    struct addrinfo *result = NULL;
    int fd = FLOM_NULL_FD;
    
    FLOM_TRACE(("flom_tcp_listen\n"));
    TRY {
        struct addrinfo hints, *gai = NULL;
        int errcode;
        char port[100];
        struct sockaddr_in6 sa6;
        struct sockaddr *sa = NULL;

        memset(&hints, 0, sizeof(hints));
        hints.ai_flags = AI_PASSIVE;
        hints.ai_family = obj->domain;
        hints.ai_socktype = obj->socket_type;
        hints.ai_protocol = IPPROTO_TCP;
        snprintf(port, sizeof(port), "%u",
                 flom_config_get_unicast_port(obj->config));
        FLOM_TRACE(("flom_tcp_listen: binding address '%s' "
                    "and port %s\n", flom_config_get_unicast_address(
                        obj->config), port));

        if (0 != (errcode = getaddrinfo(
                      flom_config_get_unicast_address(obj->config),
                      port, &hints, &result))) {
            FLOM_TRACE(("flom_tcp_listen/getaddrinfo(): "
                        "errcode=%d '%s'\n", errcode, gai_strerror(errcode)));
            THROW(GETADDRINFO_ERROR);
        } else {
            int bound = FALSE;
            int sock_opt = 1;
            FLOM_TRACE_ADDRINFO("flom_tcp_listen/getaddrinfo(): ",
                                result);
            /* traverse the list and try to bind... */
            gai = result;
            while (NULL != gai && !bound) {
                sa = gai->ai_addr;
                /* IPv6 addresses could need sin6_scope_id set if the user
                   specified a network interface */
                if (AF_INET6 == gai->ai_family &&
                    NULL != flom_config_get_network_interface(obj->config)) {
                    memcpy(&sa6, sa, gai->ai_addrlen);
                    sa6.sin6_scope_id = flom_config_get_sin6_scope_id(
                        obj->config);
                    sa = (struct sockaddr *)&sa6;
                    FLOM_TRACE(("flom_tcp_listen: overriding field "
                                "sin6_scope_id with value %u\n",
                                sa6.sin6_scope_id));
                }
                FLOM_TRACE_SOCKADDR("flom_tcp_listen: ai_addr ",
                                    (void *)sa, gai->ai_addrlen);
                if (-1 == (fd = socket(gai->ai_family, gai->ai_socktype,
                                       gai->ai_protocol))) {
                    FLOM_TRACE(("flom_tcp_listen/socket(): "
                                "errno=%d '%s', skipping...\n", errno,
                                strerror(errno)));
                    gai = gai->ai_next;
                } else if (-1 == setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
                                            (void *)&sock_opt,
                                            sizeof(sock_opt))) {
                    FLOM_TRACE(("flom_tcp_listen/setsockopt() : "
                                "errno=%d '%s', skipping...\n", errno,
                                strerror(errno)));
                    gai = gai->ai_next;
                    close(fd);
                    fd = FLOM_NULL_FD;
                } else if (-1 == bind(fd, sa, gai->ai_addrlen)) {
                    FLOM_TRACE(("flom_tcp_listen/bind() : "
                                "errno=%d '%s', skipping...\n", errno,
                                strerror(errno)));
                    gai = gai->ai_next;
                    close(fd);
                    fd = FLOM_NULL_FD;
                } else {
                    bound = TRUE;
                    FLOM_TRACE(("flom_tcp_listen: bound!\n"));
                }
            } /* while (NULL != gai && !bound) */
            if (!bound)
                THROW(BIND_ERROR);
        }        
        if (-1 == listen(fd, LISTEN_BACKLOG))
            THROW(LISTEN_ERROR);
        /* set output values */
        obj->sockfd = fd;
        obj->addrlen = gai->ai_addrlen;
        memcpy(&obj->sa_storage, sa, obj->addrlen);
        fd = FLOM_NULL_FD; /* avoid socket close by clean-up section */        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case GETADDRINFO_ERROR:
                ret_cod = FLOM_RC_GETADDRINFO_ERROR;
                break;
            case BIND_ERROR:
                ret_cod = FLOM_RC_BIND_ERROR;
                break;
            case LISTEN_ERROR:
                ret_cod = FLOM_RC_LISTEN_ERROR;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    if (NULL != result)
        freeaddrinfo(result);
    if (FLOM_NULL_FD != fd)
        close(fd);
    FLOM_TRACE(("flom_tcp_listen/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
Пример #4
0
int flom_tcp_connect(flom_tcp_t *obj)
{
    enum Exception { GETADDRINFO_ERROR
                     , CONNECTION_REFUSED
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;

    struct addrinfo *result = NULL;
    int fd = FLOM_NULL_FD;
    
    FLOM_TRACE(("flom_tcp_connect\n"));
    TRY {
        struct addrinfo hints;
        const struct addrinfo *p = NULL;
        char port_string[100];
        int errcode;
        
        FLOM_TRACE(("flom_tcp_connect: connecting to address '%s' "
                    "and port %d\n",
                    flom_config_get_unicast_address(obj->config),
                    flom_config_get_unicast_port(obj->config)));
        memset(&hints, 0, sizeof(hints));

        hints.ai_flags = AI_CANONNAME;
        /* interface name is specified, IPv6 is forced */
        if (NULL != flom_config_get_network_interface(obj->config))
            hints.ai_family = AF_INET6;
        else
            hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        snprintf(port_string, sizeof(port_string), "%u",
                 flom_config_get_unicast_port(obj->config));
        
        if (0 != (errcode = getaddrinfo(
                      flom_config_get_unicast_address(obj->config),
                      port_string, &hints, &result))) {
            FLOM_TRACE(("flom_tcp_connect/getaddrinfo(): "
                        "errcode=%d '%s'\n", errcode, gai_strerror(errcode)));
            THROW(GETADDRINFO_ERROR);
        } 
        FLOM_TRACE_ADDRINFO("flom_tcp_connect/getaddrinfo(): ",
                            result);
        if (NULL == (p = flom_tcp_try_connect(obj->config, result, &fd))) {
            /* domain must be set even if the connection failed because it's
               necessary to start a new daemon */
            obj->domain = result->ai_family;
            THROW(CONNECTION_REFUSED);
        }

        obj->domain = result->ai_family;
        obj->sockfd = fd;
        obj->socket_type = hints.ai_socktype;
        obj->addrlen = p->ai_addrlen;
        memcpy(&obj->sa_storage, p->ai_addr, obj->addrlen);
        FLOM_TRACE(("flom_tcp_connect: domain=%d, sockfd=%d, socket_type=%d, "
                    "addrlen=%u\n", obj->domain, obj->sockfd, obj->addrlen));
        FLOM_TRACE_SOCKADDR("flom_tcp_connect: ", &obj->sa, obj->addrlen);
        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case GETADDRINFO_ERROR:
                ret_cod = FLOM_RC_GETADDRINFO_ERROR;
                break;
            case CONNECTION_REFUSED:
                ret_cod = FLOM_RC_CONNECTION_REFUSED;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    if (NULL != result)
        freeaddrinfo(result);
    /* in case of error, close the socket */
    if (FLOM_RC_OK != ret_cod && FLOM_NULL_FD != fd)
        close(fd);
    FLOM_TRACE(("flom_tcp_connect/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
Пример #5
0
const char *flom_handle_get_unicast_address(const flom_handle_t *handle)
{
    FLOM_TRACE(("flom_handle_get_unicast_address: value='%s'\n",
                STRORNULL(flom_config_get_unicast_address(handle->config))));
    return (const char *)flom_config_get_unicast_address(handle->config);
}