예제 #1
0
파일: flom_handle.c 프로젝트: tiian/flom
void flom_handle_delete(flom_handle_t *handle)
{
    /* dummy loop */
    while (TRUE) {
        int ret_cod;
        
        /* check flom library is initialized */
        if (FLOM_RC_OK != flom_init_check())
            break;
        FLOM_TRACE(("flom_handle_delete: handle=%p\n", handle));
        /* check handle is not NULL */
        if (NULL == handle) {
            FLOM_TRACE(("flom_handle_delete: handle is null, skipping...\n"));
            break;
        }
        /* clean object handle */
        if (FLOM_RC_OK != (ret_cod = flom_handle_clean(handle))) {
            FLOM_TRACE(("flom_handle_new: flom_handle_clean returned %d, "
                        "ignoring it and going on...\n", ret_cod));
        }
        /* reset the object handle to prevent misuse of the associated
           memory */
        memset(handle, 0, sizeof(flom_handle_t));
        /* remove object handle */
        g_free(handle);
        FLOM_TRACE(("flom_handle_new: deallocated handle %p\n", handle));
        /* exit the loop after one cycle */
        break;
    } /* while (TRUE) */
    FLOM_TRACE(("flom_handle_delete: exiting\n"));
}
예제 #2
0
int flom_resource_simple_can_lock(flom_resource_t *resource,
                                  flom_lock_mode_t lock)
{
    static const flom_lock_mode_t lock_table[
        FLOM_LOCK_MODE_N][FLOM_LOCK_MODE_N] =
        { { TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE } ,
          { TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  FALSE } ,
          { TRUE,  TRUE,  TRUE,  FALSE, FALSE, FALSE } ,
          { TRUE,  TRUE,  FALSE, TRUE,  FALSE, FALSE } ,
          { TRUE,  TRUE,  FALSE, FALSE, FALSE, FALSE } ,
          { TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE } };
    
    GSList *p = NULL;
    flom_lock_mode_t old_lock;
    int can_lock = TRUE;
    
    FLOM_TRACE(("flom_resource_simple_can_lock: checking lock=%d\n", lock));
    p = resource->data.simple.holders;
    while (NULL != p) {
        old_lock = ((struct flom_rsrc_conn_lock_s *)p->data)->info.lock_mode;
        FLOM_TRACE(("flom_resource_simple_can_lock: current_lock=%d, "
                    "asked_lock=%d, lock_table[%d][%d]=%d\n",
                    old_lock, lock, old_lock, lock,
                    lock_table[old_lock][lock]));
        can_lock &= lock_table[old_lock][lock];
        if (!can_lock)
            break;
        else
            p = p->next;
    } /* while (NULL != p) */
    return can_lock;
}
예제 #3
0
파일: flom_handle.c 프로젝트: tiian/flom
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;
}
예제 #4
0
파일: flom_tcp.c 프로젝트: tiian/flom
int flom_tcp_close(flom_tcp_t *obj)
{
    enum Exception { CLOSE_ERROR
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    FLOM_TRACE(("flom_tcp_close\n"));
    TRY {
        if (FLOM_NULL_FD == obj->sockfd) {
            FLOM_TRACE(("flom_tcp_close: sockfd is NULL, skipping...\n"));
        } else {
            if (0 != close(obj->sockfd))
                THROW(CLOSE_ERROR);
            obj->sockfd = FLOM_NULL_FD;
        } /* if (FLOM_NULL_FD == obj->sockfd) */
        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case CLOSE_ERROR:
                ret_cod = FLOM_RC_CLOSE_ERROR;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    FLOM_TRACE(("flom_tcp_close/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #5
0
void flom_resource_simple_free(flom_resource_t *resource)
{    
    /* clean-up holders list... */
    FLOM_TRACE(("flom_resource_simple_free: cleaning-up holders list...\n"));
    while (NULL != resource->data.simple.holders) {
        struct flom_rsrc_conn_lock_s *cl =
            (struct flom_rsrc_conn_lock_s *)resource->data.simple.holders->data;
        resource->data.simple.holders = g_slist_remove(
            resource->data.simple.holders, cl);
        flom_rsrc_conn_lock_delete(cl);
    }
    resource->data.simple.holders = NULL;
    /* clean-up waitings queue... */
    FLOM_TRACE(("flom_resource_simple_free: cleaning-up waitings queue...\n"));
    while (!g_queue_is_empty(resource->data.simple.waitings)) {
        struct flom_rsrc_conn_lock_s *cl =
            (struct flom_rsrc_conn_lock_s *)g_queue_pop_head(
                resource->data.simple.waitings);
        flom_rsrc_conn_lock_delete(cl);
    }
    g_queue_free(resource->data.simple.waitings);
    resource->data.simple.waitings = NULL;
    /* releasing resource name */
    if (NULL != resource->name)
        g_free(resource->name);
    resource->name = NULL;
}
예제 #6
0
파일: flom_conn.c 프로젝트: tiian/flom
int flom_conn_set_keepalive(flom_config_t *config, int fd)
{
    enum Exception { NULL_OBJECT
                     , SETSOCKOPT_ERROR1
                     , SETSOCKOPT_ERROR2
                     , SETSOCKOPT_ERROR3
                     , SETSOCKOPT_ERROR4
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    FLOM_TRACE(("flom_conn_set_keepalive\n"));
    TRY {
        int optval;
        socklen_t optlen = sizeof(optval);
        
        if (FLOM_NULL_FD == fd)
            THROW(NULL_OBJECT);

        FLOM_TRACE(("flom_conn_set_keepalive: setting SO_KEEPALIVE "
                    "for socket fd=%d\n", fd));
        /* set SO_KEEPALIVE feature for this socket */
        optval = 1;
        if (-1 == setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen))
            THROW(SETSOCKOPT_ERROR1);
        /* set tcp_keepalive_time parameter related to SO_KEEPALIVE */
        optval = flom_config_get_tcp_keepalive_time(config);
        if (-1 == setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &optval, optlen))
            THROW(SETSOCKOPT_ERROR2);
        /* set tcp_keepalive_intvl parameter related to SO_KEEPALIVE */
        optval = flom_config_get_tcp_keepalive_intvl(config);
        if (-1 == setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &optval, optlen))
            THROW(SETSOCKOPT_ERROR3);
        /* set tcp_keepalive_probes parameter related to SO_KEEPALIVE */
        optval = flom_config_get_tcp_keepalive_probes(config);
        if (-1 == setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &optval, optlen))
            THROW(SETSOCKOPT_ERROR4);
        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case NULL_OBJECT:
                ret_cod = FLOM_RC_NULL_OBJECT;
                break;
            case SETSOCKOPT_ERROR1:
            case SETSOCKOPT_ERROR2:
            case SETSOCKOPT_ERROR3:
            case SETSOCKOPT_ERROR4:
                ret_cod = FLOM_RC_SETSOCKOPT_ERROR;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    FLOM_TRACE(("flom_conn_set_keepalive/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #7
0
파일: flom_tcp.c 프로젝트: tiian/flom
gchar *flom_tcp_retrieve_peer_name(const flom_tcp_t *obj)
{
    struct sockaddr_storage sa;
    socklen_t addrlen = sizeof(sa);
    char host[NI_MAXHOST+1];
    char serv[NI_MAXSERV+1];
    int ret_cod;
    char *tmp;
    size_t tmp_size;

    memset(&sa, 0, sizeof(sa));
    if (0 != getpeername(obj->sockfd, (struct sockaddr *)&sa, &addrlen)) {
        FLOM_TRACE(("flom_tcp_retrieve_peer_name/getpeername: errno=%d\n",
                    errno));
        return NULL;
    }
    if (0 != (ret_cod = getnameinfo(
                  (struct sockaddr *)&sa, addrlen,
                  host, sizeof(host), serv, sizeof(serv),
                  NI_NUMERICHOST|NI_NUMERICSERV))) {
        FLOM_TRACE(("flom_tcp_retrieve_peer_name/getnameinfo: ret_cod=%d, "
                    "errno=%d\n", ret_cod, errno));
        return NULL;
    }
    tmp_size = strlen(host) + strlen(serv) + 2;
    if (NULL != (tmp = g_try_malloc0(tmp_size))) {
        snprintf(tmp, tmp_size, "%s/%s", host, serv);
    }
    return tmp;
}
예제 #8
0
파일: flom_handle.c 프로젝트: tiian/flom
int flom_handle_clean(flom_handle_t *handle)
{
    enum Exception { FLOM_HANDLE_UNLOCK_ERROR
                     , API_INVALID_SEQUENCE
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    /* check flom library is initialized */
    if (FLOM_RC_OK != (ret_cod = flom_init_check()))
        return ret_cod;
    
    FLOM_TRACE(("flom_handle_clean\n"));
    TRY {
        /* is the handle locked? we must unlock it before going on... */
        if (FLOM_HANDLE_STATE_LOCKED == handle->state) {
            if (FLOM_RC_OK != (ret_cod = flom_handle_unlock(handle)))
                THROW(FLOM_HANDLE_UNLOCK_ERROR);
        }
        /* check handle state */
        if (FLOM_HANDLE_STATE_INIT != handle->state &&
            FLOM_HANDLE_STATE_DISCONNECTED != handle->state) {
            FLOM_TRACE(("flom_handle_clean: handle->state=%d\n",
                        handle->state));
            THROW(API_INVALID_SEQUENCE);
        }
        /* release memory allocated for configuration object */
        flom_config_free(handle->config);
        g_free(handle->config);
        handle->config = NULL;
        /* release memory of connection data structure */
        g_free(handle->conn);
        handle->conn = NULL;
        /* release memory of locked element */
        g_free(handle->locked_element);
        handle->locked_element = NULL;
        /* clean handle state */
        handle->state = FLOM_HANDLE_STATE_CLEANED;
        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case FLOM_HANDLE_UNLOCK_ERROR:
                break;
            case API_INVALID_SEQUENCE:
                ret_cod = FLOM_RC_API_INVALID_SEQUENCE;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    FLOM_TRACE(("flom_handle_clean/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #9
0
파일: flom_tcp.c 프로젝트: tiian/flom
int flom_tcp_recv(const flom_tcp_t *obj, void *buf, size_t len,
                  size_t *received,
                  struct sockaddr *src_addr, socklen_t *addrlen)
{
    enum Exception { INVALID_SOCKET_TYPE
                     , RECV_ERROR
                     , RECVFROM_ERROR
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    FLOM_TRACE(("flom_tcp_recv\n"));
    TRY {
        switch (obj->socket_type) {
            case SOCK_STREAM:
                if (0 > (*received = recv(obj->sockfd, buf, len, 0)))
                    THROW(RECV_ERROR);
                break;
            case SOCK_DGRAM:
                if (0 > (*received = recvfrom(
                             obj->sockfd, buf, len, 0,
                             (struct sockaddr *)src_addr, addrlen)))
                    THROW(RECVFROM_ERROR);
                FLOM_TRACE_HEX_DATA("flom_tcp_recv: from ",
                                    (void *)src_addr, *addrlen);        
                break;
            default:
                THROW(INVALID_SOCKET_TYPE);
        } /* switch (type) */
        
        FLOM_TRACE(("flom_tcp_recv: fd=%d returned "
                    SSIZE_T_FORMAT " bytes '%*.*s'\n", obj->sockfd,
                    *received, *received, *received, buf));

        THROW(NONE);
    } CATCH {
        switch (excp) {
            case INVALID_SOCKET_TYPE:
                ret_cod = FLOM_RC_INVALID_OPTION;
                break;
            case RECV_ERROR:
                ret_cod = FLOM_RC_RECV_ERROR;
                break;
            case RECVFROM_ERROR:
                ret_cod = FLOM_RC_RECVFROM_ERROR;
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    FLOM_TRACE(("flom_tcp_recv/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #10
0
파일: flom_conn.c 프로젝트: tiian/flom
void flom_conn_trace(const flom_conn_t *conn)
{
    FLOM_TRACE(("flom_conn_trace: object=%p\n", conn));
    FLOM_TRACE(("flom_conn_trace: "
                "fd=%d, type=%d, state=%d, wait=%d, msg=%p, parser=%p, "
                "addr_len=%d\n",
                flom_tcp_get_sockfd(&conn->tcp),
                flom_tcp_get_socket_type(&conn->tcp),
                conn->state, conn->wait, conn->msg, conn->parser,
                flom_tcp_get_addrlen(&conn->tcp)));
}
예제 #11
0
파일: flom_conn.c 프로젝트: tiian/flom
int flom_conn_send(flom_conn_t *obj, const void *buf, size_t len)
{
    int ret_cod = FLOM_RC_OK;
    FLOM_TRACE(("flom_conn_send\n"));

    if (NULL != obj->tls)
        ret_cod = flom_tls_send(obj->tls, buf, len);
    else
        ret_cod = flom_tcp_send(&obj->tcp, buf, len);
    FLOM_TRACE(("flom_conn_send/"
                "ret_cod=%d/errno=%d\n", ret_cod, errno));
    return ret_cod;
}
예제 #12
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_resource_timeout(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_resource_timeout: "
                "old value=%d, new value=%d\n",
                flom_config_get_resource_timeout(handle->config), value));
    return flom_config_set_resource_timeout(handle->config, (int)value);
}
예제 #13
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_resource_quantity(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_resource_quantity: "
                "old value=%d, new value=%d\n",
                flom_config_get_resource_quantity(handle->config), value));
    flom_config_set_resource_quantity(handle->config, (int)value);
}
예제 #14
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_resource_create(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_resource_create: "
                "old value=%d, new value=%d\n",
                flom_config_get_resource_create(handle->config), value));
    return flom_config_set_resource_create(handle->config, value);
}
예제 #15
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_discovery_ttl(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_discovery_ttl: "
                "old value=%d, new value=%d\n",
                flom_config_get_discovery_ttl(handle->config), value));
    flom_config_set_discovery_ttl(handle->config, (gint)value);
}
예제 #16
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_unicast_port(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_unicast_port: "
                "old value=%d, new value=%d\n",
                flom_config_get_unicast_port(handle->config), value));
    flom_config_set_unicast_port(handle->config, (gint)value);
}
예제 #17
0
파일: flom_handle.c 프로젝트: tiian/flom
const char *flom_handle_get_tls_ca_certificate(const flom_handle_t *handle)
{
    FLOM_TRACE(("flom_handle_get_tls_ca_certificate: value='%s'\n",
                STRORNULL(
                    flom_config_get_tls_ca_certificate(handle->config))));
    return (const char *)flom_config_get_tls_ca_certificate(handle->config);
}
예제 #18
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_lock_mode(flom_handle_t *handle, flom_lock_mode_t value)
{
    FLOM_TRACE(("flom_handle_set_lock_mode: "
                "old value=%d, new value=%d\n",
                flom_config_get_lock_mode(handle->config), value));
    flom_config_set_lock_mode(handle->config, value);
}
예제 #19
0
파일: flom_tcp.c 프로젝트: tiian/flom
void flom_tcp_init(flom_tcp_t *obj, flom_config_t *config)
{
    FLOM_TRACE(("flom_tcp_init\n"));
    /* memory reset */
    memset(obj, 0, sizeof(flom_tcp_t));
    obj->config = config;
}
예제 #20
0
파일: flom_handle.c 프로젝트: tiian/flom
const char *flom_handle_get_trace_filename(const flom_handle_t *handle)
{
    FLOM_TRACE(("flom_handle_get_trace_filename: value='%s'\n",
                STRORNULL(flom_config_get_command_trace_file(
                              handle->config))));
    return (const char *)flom_config_get_command_trace_file(handle->config);
}
예제 #21
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_trace_filename(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_trace_filename: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_command_trace_file(handle->config)),
                STRORNULL(value)));
    flom_config_set_command_trace_file(handle->config, (const gchar *)value);
}
예제 #22
0
파일: flom_conn.c 프로젝트: tiian/flom
int flom_conn_authenticate(flom_conn_t *conn, const gchar *peer_id,
                           int tls_check_peer_id)
{
    enum Exception { TLS_CERT_CHECK_ERROR
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    gchar *unique_id = NULL;
    gchar *peer_addr = NULL;

    FLOM_TRACE(("flom_conn_authenticate\n"));
    TRY {
        if (NULL == flom_conn_get_tls(conn)) {
            FLOM_TRACE(("flom_conn_authenticate: this is not a TLS coonection "
                        "and authentication can not be performed\n"));
        } else if (tls_check_peer_id) {
            peer_addr = flom_tcp_retrieve_peer_name(
                flom_conn_get_tcp(conn));
            if (FLOM_RC_OK != (ret_cod = flom_tls_cert_check(
                                   flom_conn_get_tls(conn), peer_id,
                                   peer_addr))) {
                THROW(TLS_CERT_CHECK_ERROR);
            }            
        } /* if (tls_check_peer_id) */
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case TLS_CERT_CHECK_ERROR:
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    /* unique id object clean-up */
    if (NULL != unique_id)
        g_free(unique_id);
    /* peer address object clean-up */
    if (NULL != peer_addr)
        g_free(peer_addr);
    FLOM_TRACE(("flom_conn_authenticate/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #23
0
파일: flom_handle.c 프로젝트: 3manuek/flom
void flom_handle_set_resource_idle_lifespan(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_resource_idle_lifespan: "
                "old value=%d, new value=%d\n",
                flom_config_get_resource_idle_lifespan(handle->config),
                value));
    flom_config_set_resource_idle_lifespan(handle->config, (gint)value);
}
예제 #24
0
파일: flom_handle.c 프로젝트: 3manuek/flom
int flom_handle_set_resource_name(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_resource_name: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_resource_name(handle->config)),
                STRORNULL(value)));
    return flom_config_set_resource_name(handle->config, (const gchar *)value);
}
예제 #25
0
파일: flom_conn.c 프로젝트: tiian/flom
void flom_conn_delete(flom_conn_t *obj)
{
    FLOM_TRACE(("flom_conn_delete: obj=%p\n", obj));
    if (NULL != obj) {
        FLOM_TRACE(("flom_conn_delete: obj->msg=%p\n", obj->msg));
        /* remove msg struct */
        if (NULL != obj->msg) {
            flom_msg_free(obj->msg);
            g_free(obj->msg);
            obj->msg = NULL;
        }
        /* clean TLS object */
        flom_tls_delete(obj->tls);
        obj->tls = NULL;
        /* remove object itself */
        g_free(obj);
    }
}
예제 #26
0
파일: flom_handle.c 프로젝트: tiian/flom
int flom_handle_set_unicast_port(flom_handle_t *handle, int value)
{
    FLOM_TRACE(("flom_handle_set_unicast_port: "
                "old value=%d, new value=%d\n",
                flom_config_get_unicast_port(handle->config), value));
    switch (handle->state) {
        case FLOM_HANDLE_STATE_INIT:
        case FLOM_HANDLE_STATE_DISCONNECTED:
            flom_config_set_unicast_port(handle->config, (gint)value);
            break;
        default:
            FLOM_TRACE(("flom_handle_set_unicast_port: state %d " \
                        "is not compatible with set operation\n",
                        handle->state));
            return FLOM_RC_API_IMMUTABLE_HANDLE;
    } /* switch (handle->state) */
    return FLOM_RC_OK;
}
예제 #27
0
파일: flom_tcp.c 프로젝트: tiian/flom
const struct addrinfo *flom_tcp_try_connect(
    flom_config_t *config, const struct addrinfo *gai, int *fd)
{
    const struct addrinfo *found = NULL; 
    *fd = FLOM_NULL_FD;
    /* traverse the list and try to connect... */
    while (NULL != gai && NULL == found) {
        struct sockaddr_in6 sa6;
        struct sockaddr *sa = gai->ai_addr;
        /* IPv6 addresses could need sin6_scope_id set if the user specified
           a network interface */
        FLOM_TRACE_SOCKADDR("flom_tcp_try_connect: sa ",
                            sa, gai->ai_addrlen);
        if (AF_INET6 == sa->sa_family &&
            NULL != flom_config_get_network_interface(config)) {
            memcpy(&sa6, sa, gai->ai_addrlen);
            sa6.sin6_scope_id = flom_config_get_sin6_scope_id(config);
            sa = (struct sockaddr *)&sa6;
            FLOM_TRACE(("flom_tcp_try_connect: overriding field "
                        "sin6_scope_id with value %u\n", sa6.sin6_scope_id));
        }
            
        if (FLOM_NULL_FD == (*fd = socket(gai->ai_family, gai->ai_socktype,
                                          gai->ai_protocol))) {
            FLOM_TRACE(("flom_tcp_try_connect/socket(): "
                        "errno=%d '%s', skipping...\n", errno,
                        strerror(errno)));
            gai = gai->ai_next;
        } else {
            FLOM_TRACE_SOCKADDR("flom_tcp_try_connect: sa ",
                                sa, gai->ai_addrlen);
            if (-1 == connect(*fd, sa, gai->ai_addrlen)) {
                FLOM_TRACE(("flom_tcp_try_connect/connect(): "
                            "errno=%d '%s', skipping...\n", errno,
                            strerror(errno)));
                gai = gai->ai_next;
                close(*fd);
                *fd = FLOM_NULL_FD;
            } else
                found = gai;
        } /* if (-1 == (*fd = socket( */
    } /* while (NULL != gai && !connected) */
    return found;
}
예제 #28
0
파일: flom_handle.c 프로젝트: tiian/flom
int flom_handle_set_trace_filename(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_trace_filename: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_command_trace_file(handle->config)),
                STRORNULL(value)));
    flom_config_set_command_trace_file(handle->config, (const gchar *)value);
    FLOM_TRACE_REOPEN(flom_config_get_command_trace_file(handle->config),
                      FALSE);
    return FLOM_RC_OK;
}
예제 #29
0
파일: flom_conn.c 프로젝트: tiian/flom
int flom_conn_terminate(flom_conn_t *obj)
{
    enum Exception { TCP_CLOSE
                     , NONE } excp;
    int ret_cod = FLOM_RC_INTERNAL_ERROR;
    
    FLOM_TRACE(("flom_conn_terminate\n"));
    TRY {
        if (FLOM_CONN_STATE_REMOVE != flom_conn_get_state(obj)) {
            flom_conn_set_state(obj, FLOM_CONN_STATE_REMOVE);
            if (FLOM_NULL_FD == flom_tcp_get_sockfd(&obj->tcp)) {
                FLOM_TRACE(("flom_conn_terminate: connection %p already "
                            "closed, skipping...\n", obj));
            } else {
                FLOM_TRACE(("flom_conn_terminate: closing fd=%d\n",
                            flom_tcp_get_sockfd(&obj->tcp)));
                if (FLOM_RC_OK != (ret_cod = flom_tcp_close(&obj->tcp)))
                    THROW(TCP_CLOSE);
            }
        } else {
            FLOM_TRACE(("flom_conn_terminate: connection %p already "
                        "in state %d, skipping...\n", obj,
                        flom_conn_get_state(obj)));
        } /* if (FLOM_CONN_STATE_REMOVE == flom_conn_get_state(c)) */
        
        THROW(NONE);
    } CATCH {
        switch (excp) {
            case TCP_CLOSE:
                break;
            case NONE:
                ret_cod = FLOM_RC_OK;
                break;
            default:
                ret_cod = FLOM_RC_INTERNAL_ERROR;
        } /* switch (excp) */
    } /* TRY-CATCH */
    FLOM_TRACE(("flom_conn_terminate/excp=%d/"
                "ret_cod=%d/errno=%d\n", excp, ret_cod, errno));
    return ret_cod;
}
예제 #30
0
파일: flom_handle.c 프로젝트: tiian/flom
int flom_handle_set_resource_name(flom_handle_t *handle, const char *value)
{
    FLOM_TRACE(("flom_handle_set_resource_name: "
                "old value='%s', new value='%s'\n",
                STRORNULL(flom_config_get_resource_name(handle->config)),
                STRORNULL(value)));
    switch (handle->state) {
        case FLOM_HANDLE_STATE_INIT:
        case FLOM_HANDLE_STATE_DISCONNECTED:
        case FLOM_HANDLE_STATE_CONNECTED:
            flom_config_set_resource_name(handle->config,
                                          (const gchar *)value);
            break;
        default:
            FLOM_TRACE(("flom_handle_set_resource_name: state %d " \
                        "is not compatible with set operation\n",
                        handle->state));
            return FLOM_RC_API_IMMUTABLE_HANDLE;
    } /* switch (handle->state) */
    return FLOM_RC_OK;
}