Exemplo n.º 1
0
/**
 *  sip_create_IPC_sock creates and bind the socket for IPC.
 *
 *  @param[in]name - pointer to the const. character for the
 *                  IPC address (name) to be bound when the
 *                  IPC socket is successfully created.
 *
 *  @return cpr_socket_t - Returns a valid CPR's socket if
 *                   the socket is created sucessafully otherwise
 *                   returns INVALID_SOCKET.
 *  @pre    (name != NULL)
 */
static cpr_socket_t sip_create_IPC_sock (const char *name)
{
    const char *fname = "sip_create_IPC_sock";
    cpr_socket_t sock;
    cpr_sockaddr_un_t addr;

    /* Create socket */
    sock = cprSocket(AF_LOCAL, SOCK_DGRAM, 0);
    if (sock == INVALID_SOCKET) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSocket() returned error"
                          " errno=%d\n", fname, cpr_errno);
        return (INVALID_SOCKET);
    }

    /* Bind to the local socket */
    cpr_set_sockun_addr(&addr, name, getpid());

    /* make sure file doesn't already exist */
    unlink(addr.sun_path);

    /* do the bind */
    if (cprBind(sock, (cpr_sockaddr_t *)&addr,
                cpr_sun_len(addr)) == CPR_FAILURE) {
        (void) sipSocketClose(sock, FALSE);
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprBind() failed"
                          " errno=%d\n", fname, cpr_errno);
        return (INVALID_SOCKET);
    }
    return (sock);
}
int
sip_platform_udp_channel_create (cpr_ip_mode_e ip_mode, cpr_socket_t *s,
                                 cpr_ip_addr_t *remote_ipaddr,
                                 uint16_t remote_port,
                                 uint32_t local_udp_port)
{
    static const char *fname = "sip_platform_udp_channel_create";
    cpr_sockaddr_storage sock_addr;
    uint16_t       addr_len;
    cpr_sockaddr_storage local_sock_addr;
    cpr_ip_addr_t local_signaladdr;

    int tos_dscp_val = 0; // set to default if there is no config. for dscp

    CPR_IP_ADDR_INIT(local_signaladdr);

    if (*s != INVALID_SOCKET) {
        (void) sipSocketClose(*s, FALSE);
    }

    if (ip_mode == CPR_IP_MODE_IPV6 ||
        ip_mode == CPR_IP_MODE_DUAL) {
        af_family_connect = AF_INET6;
    } else {
        af_family_connect = AF_INET;
    }
    /*
     * Create socket
     */
    *s = cprSocket(af_family_connect, SOCK_DGRAM, 0);
    if (*s == INVALID_SOCKET) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                          fname, "cprSocket unable to open socket",
                          cpr_errno);
        /* Try opening ipv4 socket */
        if (ip_mode == CPR_IP_MODE_DUAL) {

            CCSIP_DEBUG_TASK("%s: cprSocket Open failed for IPv6 trying IPv4",
                            fname);
            af_family_connect = AF_INET;
            *s = cprSocket(af_family_connect, SOCK_DGRAM, 0);
            if (*s == INVALID_SOCKET) {

                CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                              fname, "cprSocket unable to open AF_INET socket",
                             cpr_errno);
                return SIP_ERROR;
            }
        }
    }

    sip_config_get_net_device_ipaddr(&local_signaladdr);
    memset(&local_sock_addr, 0, sizeof(local_sock_addr));

    (void) sip_set_sockaddr(&local_sock_addr, af_family_connect, local_signaladdr, 0, &addr_len);
    CCSIP_DEBUG_REG_STATE(DEB_F_PREFIX"local_signaladdr.u.ip4=%x\n",
        DEB_F_PREFIX_ARGS(SIP_SDP, fname), local_signaladdr.u.ip4);

    if(cprBind(*s, (cpr_sockaddr_t *)&local_sock_addr, addr_len)){
       CCSIP_DEBUG_ERROR(SIP_F_PREFIX"UDP bind failed with errno %d\n", fname, cpr_errno);
       (void) sipSocketClose(*s, FALSE);
       *s = INVALID_SOCKET;
       return SIP_ERROR;
    }

    /*
     * Connect to remote address
     */
    (void) sip_set_sockaddr(&sock_addr, af_family_connect, *remote_ipaddr,
                            remote_port, &addr_len);

 /*   if (cprConnect(*s, (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                          fname, "cprConnect", cpr_errno);
        (void) sipSocketClose(*s, FALSE);
        *s = INVALID_SOCKET;
          return SIP_ERROR;
    }
*/
    // set IP tos/dscp value for SIP messaging
    config_get_value(CFGID_DSCP_FOR_CALL_CONTROL, (int *)&tos_dscp_val,
                     sizeof(tos_dscp_val));

    if (cprSetSockOpt(*s, SOL_IP, IP_TOS, (void *)&tos_dscp_val,
                      sizeof(tos_dscp_val)) == CPR_FAILURE) {
        // do NOT take hard action; just log the error and move on
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"Unable to set IP TOS %d on UDP socket. "
                          "cpr_errno = %d\n", fname, tos_dscp_val, cpr_errno);
    }
    return SIP_OK;
}
int
sip_platform_udp_channel_listen (cpr_ip_mode_e ip_mode, cpr_socket_t *s,
                                 cpr_ip_addr_t *local_ipaddr,
                                 uint16_t local_port)
{
    static const char fname[] = "sip_platform_udp_channel_listen";
    cpr_sockaddr_storage sock_addr;
    uint16_t       addr_len;

    /*
     * If socket passed is is not INVALID_SOCKET close it first
     */

    if (*s != INVALID_SOCKET) {
        if (sipSocketClose(*s, FALSE) != CPR_SUCCESS) {
            CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                              fname, "sipSocketClose", cpr_errno);
        }
        sip_platform_task_reset_listen_socket(*s);
    }

    /*
     * Create a socket
     */
    if (ip_mode == CPR_IP_MODE_IPV6 ||
        ip_mode == CPR_IP_MODE_DUAL) {
        af_family_listen = AF_INET6;
    } else {
        af_family_listen = AF_INET;
    }

    *s = cprSocket(af_family_listen, SOCK_DGRAM, 0);
    if (*s == INVALID_SOCKET) {
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                          fname, "cprSocket unable to open socket", cpr_errno);
        if (ip_mode == CPR_IP_MODE_DUAL) {

            af_family_listen = AF_INET;
            CCSIP_DEBUG_TASK(DEB_F_PREFIX"Socket open failed for IPv6 using IPv4 address.",
                             DEB_F_PREFIX_ARGS(SIP_SDP, fname));

            *s = cprSocket(af_family_listen, SOCK_DGRAM, 0);
            if (*s == INVALID_SOCKET) {
                CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                              fname, "cprSocket unable to open socket for IPv4",
                                        cpr_errno);
                return SIP_ERROR;
            }
        }
    }

    (void) sip_set_sockaddr(&sock_addr, af_family_listen, *local_ipaddr,
                            local_port, &addr_len);

    if (cprBind(*s,  (cpr_sockaddr_t *)&sock_addr, addr_len) == CPR_FAILURE) {
        (void) sipSocketClose(*s, FALSE);
        *s = INVALID_SOCKET;
        CCSIP_DEBUG_ERROR(get_debug_string(DEBUG_GENERAL_SYSTEMCALL_FAILED),
                          fname, "cprBind", cpr_errno);
        return SIP_ERROR;
    }
    sip_platform_task_set_listen_socket(*s);

    return SIP_OK;
}