Example #1
0
void
stress_test_sll(int amt)
{
	sll l1;
	sll l2;
	gendata x, y;
	int i;

	l1 = sll_create();
	l2 = sll_create();
	assert(sll_empty(l1));
	assert(sll_empty(l2));
	printf("Filling two slls with 2 * %d items...\n", amt);
	for (i = 0; i < amt; ++i) {
		x.num = i;
		l1 = sll_prepend_head(l1, x);
		l2 = sll_prepend_head(l2, x);
		assert(!sll_empty(l1));
		assert(!sll_empty(l2));
		l1 = sll_append_head(l1, x);
		l2 = sll_append_head(l2, x);
		assert(!sll_empty(l1));
		assert(!sll_empty(l2));
	}
	assert(sll_count(l1) == (unsigned int)(2 * amt));
	assert(sll_count(l2) == (unsigned int)(2 * amt));

	l1 = sll_append(l1, l2);
	assert(sll_count(l1) == (unsigned int)(4 * amt));

	/* From now on, l2 is `invalid' */

	printf("Removing 2 * 2 * %d items from the appended sll...\n", amt);
	for (i = 0; i < (2 * amt); ++i) {
		x = sll_get_data(sll_next(l1));
		assert(!sll_empty(l1));
		l1 = sll_remove_next(l1, NULL);
		y = sll_get_data(l1);
		assert(!sll_empty(l1));
		l1 = sll_remove_head(l1, NULL);

		/*
		 * We have to count backwards in this check, since we're
		 * using the list like a stack, prepending all the time.
		 */
		assert(x.num == amt - (i % amt) - 1);
		assert(x.num == y.num);
	}
	assert(sll_empty(l1));
	sll_destroy(l1, NULL);
}
Example #2
0
// Create a new session
// FIXME - This is currently open to a DoS attack.
//         but since we have a session limit, just for opendias.
char *create_session() {
  char *session_id;

  // Check upper session count limit
  int current_session_count = sll_count( sll_findFirstElement( sessions ) );
  o_log( DEBUGM, "There are currently %d active sessions", current_session_count);
  if( current_session_count > MAX_SESSIONS ) {
    return NULL;
  }

  // Generate session key
  uuid_t uu;
  char *sid = malloc(36+1);
  uuid_generate(uu);
  uuid_unparse(uu, sid);
  session_id = o_strdup(sid);
  free(sid);
  o_log(DEBUGM, "Generated new session: %s", session_id );

  // Create new session structure
  struct session_data *session_element = malloc( sizeof(struct session_data) );
  session_element->last_accessed = time(NULL);
  session_element->session_container = sll_init();

  // Save and return
  sll_insert( sessions, o_strdup(session_id), session_element );
  return session_id;
}
/**
 * This function will append presence notification to the pending queue.
 *
 * @param[in] event_data_p - pointer to event data.
 *
 * @return none.
 *
 * @pre (event_data_p != NULL)
 */
static void append_notification_to_pending_queue (ccsip_event_data_t *event_data_p)
{
    static const char fname[] = "append_notification_to_pending_queue";
    pres_pending_notify_t *pending_notify_p;
    Presence_ext_t *event_body_p = &(event_data_p->u.presence_rpid);

    /*
     * create pending list if it is not created yet.
     */
    if (s_pending_notify_list == NULL) {
        s_pending_notify_list = sll_create(NULL);
        if (s_pending_notify_list == NULL) {
            CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
            free_event_data(event_data_p);
            return;
        }
    }

    pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list, NULL);
    while (pending_notify_p != NULL) {
        if (strncmp(pending_notify_p->presentity, event_body_p->presence_body.entity,
                    CC_MAX_DIALSTRING_LEN - 1) == 0) {
            /* replace the current state with new state */
            free_event_data(pending_notify_p->event_data_p);
            pending_notify_p->event_data_p = event_data_p;
            return;
        }
        pending_notify_p = (pres_pending_notify_t *)sll_next(s_pending_notify_list,
                                                             pending_notify_p);
    }

    /*
     * To protect from DoS attacks, do not allow more than
     * MAX_REG_LINES entries in the list.
     */
    if (sll_count(s_pending_notify_list) == MAX_REG_LINES) {
        CSFLogError("src-common", "MSC: 0/0: %s: ignoring the NOTIFY "
            "to protect from DoS attack", fname);
        free_event_data(event_data_p);
        return;
    }
    pending_notify_p = (pres_pending_notify_t *)
                       cpr_malloc(sizeof(pres_pending_notify_t));
    if (pending_notify_p == NULL) {
        CSFLogError("src-common", "MSC: 0/0: %s: out of memory", fname);
        free_event_data(event_data_p);
        return;
    }
    sstrncpy(pending_notify_p->presentity, event_body_p->presence_body.entity,
             CC_MAX_DIALSTRING_LEN);
    pending_notify_p->event_data_p = event_data_p;
    (void) sll_append(s_pending_notify_list, pending_notify_p);
    return;
}
Example #4
0
/**
 * This function will print the stats (invoked by show command)
 *
 * @param[in] none
 *
 * @return 0 always
 */
cc_int32_t show_publish_stats (cc_int32_t argc, const char *argv[])
{
    debugif_printf("------ Current PUBLISH Statistics ------\n");
    if (s_PCB_list != NULL) {
        debugif_printf("Number of PCBs allocated: %d\n", sll_count(s_PCB_list));
    } else {
        debugif_printf("Number of PCBs allocated: 0\n");
    }
    debugif_printf("Total outgoing PUBLISH requests: %d\n", outgoingPublishes);
    return 0;
}
/**
 *
 * sip_platform_task_loop
 *
 * Run the SIP task
 *
 * Parameters: arg - SIP message queue
 *
 * Return Value: None
 *
 */
void
sip_platform_task_loop (void *arg)
{
    static const char *fname = "sip_platform_task_loop";
    int pending_operations;
    uint16_t i;
    fd_set sip_read_fds;
    fd_set sip_write_fds;
    sip_tcp_conn_t *entry;

    sip_msgq = (cprMsgQueue_t) arg;
    if (!sip_msgq) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_msgq is null, exiting", fname);
        return;
    }
    sip.msgQueue = sip_msgq;

    sip_platform_task_init();
    /*
     * Initialize the SIP task
     */
    SIPTaskInit();

    if (platThreadInit("SIPStack Task") != 0) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"failed to attach thread to JVM", fname);
        return;
    }

    /*
     * Adjust relative priority of SIP thread.
     */
    (void) cprAdjustRelativeThreadPriority(SIP_THREAD_RELATIVE_PRIORITY);

    /*
     * Setup IPC socket addresses for main thread (server)
     */
    {
      char stmpdir[sizeof(sip_serv_sock_addr.sun_path)];
      sip_get_sock_dir(stmpdir, sizeof(stmpdir), SIP_MSG_SERV_SUFFIX);
      cpr_set_sockun_addr(&sip_serv_sock_addr, stmpdir, 0);
    }

    /*
     * Create IPC between the message queue thread and this main
     * thread.
     */
    sip_ipc_serv_socket = sip_create_IPC_sock(sip_serv_sock_addr.sun_path);

    if (sip_ipc_serv_socket == INVALID_SOCKET) {
        CCSIP_DEBUG_ERROR(SIP_F_PREFIX"sip_create_IPC_sock() failed:"
                          " errno=%d\n", fname, cpr_errno);
        return;
    }

    /*
     * On Win32 platform, the random seed is stored per thread; therefore,
     * each thread needs to seed the random number.  It is recommended by
     * MS to do the following to ensure randomness across application
     * restarts.
     */
    cpr_srand((unsigned int)time(NULL));

    /*
     * Set read IPC socket
     */
    sip_platform_task_set_read_socket(sip_ipc_serv_socket);

    /*
     * Let the message queue waiting thread know that the main
     * thread is ready.
     */
    main_thread_ready = TRUE;

    /*
     * Main Event Loop
     * - Forever-loop exits in sip_process_int_msg()::THREAD_UNLOAD
     */
    while (TRUE) {
        /*
         * Wait on events or timeout
         */
        sip_read_fds = read_fds;

        // start off by init to zero
        FD_ZERO(&sip_write_fds);
        // now look for sockets where data has been queued up
        for (i = 0; i < MAX_CONNECTIONS; i++) {
            entry = sip_tcp_conn_tab + i;
            if (-1 != entry->fd && entry->sendQueue && sll_count(entry->sendQueue)) {
                FD_SET(entry->fd, &sip_write_fds);
            }
        }

        pending_operations = cprSelect((nfds + 1),
                                       &sip_read_fds,
                                       &sip_write_fds,
                                       NULL, NULL);
        if (pending_operations == SOCKET_ERROR) {
            CCSIP_DEBUG_ERROR(SIP_F_PREFIX"cprSelect() failed: errno=%d."
                " Recover by initiating sip restart\n",
                              fname, cpr_errno);
            /*
             * If we have come here, then either read socket related to
             * sip_ipc_serv_socket has got corrupted, or one of the write
             * socket related to cucm tcp/tls connection.
             * We will recover, by first clearing all fds, then re-establishing
             * the connection with sip-msgq by listening on
             * sip_ipc_serv_socket.
             */
            sip_platform_task_init(); /* this clear FDs */
            sip_platform_task_set_read_socket(sip_ipc_serv_socket);

            /*
             * Since all sockets fds have been cleared above, we can not anyway
             * send or receive msg from cucm. So, there is no point
             * trying to send registration cancel msg to cucm. Also, a
             * call may be active, and in that case we do not want to
             * un-register. So, by setting sip_reg_all_failed to true, we
             * make sure that no registration cancelation attempt is made.
             */
            sip_reg_all_failed = TRUE;
            platform_reset_req(DEVICE_RESTART);
            continue;
        } else if (pending_operations) {
            /*
             * Listen socket is set only if UDP transport has been
             * configured. So see if the select return was for read
             * on the listen socket.
             */
            if ((listen_socket != INVALID_SOCKET) &&
                (sip.taskInited == TRUE) &&
                FD_ISSET(listen_socket, &sip_read_fds)) {
                sip_platform_udp_read_socket(listen_socket);
                pending_operations--;
            }

            /*
             * Check IPC for internal message queue
             */
            if (FD_ISSET(sip_ipc_serv_socket, &sip_read_fds)) {
                /* read the message to flush the buffer */
                sip_process_int_msg();
                pending_operations--;
            }

            /*
             * Check all sockets for stuff to do
             */
            for (i = 0; ((i < MAX_SIP_CONNECTIONS) &&
                         (pending_operations > 0)); i++) {
                if ((sip_conn.read[i] != INVALID_SOCKET) &&
                    FD_ISSET(sip_conn.read[i], &sip_read_fds)) {
                    /*
                     * Assume tcp
                     */
                    sip_tcp_read_socket(sip_conn.read[i]);
                    pending_operations--;
                }
                if ((sip_conn.write[i] != INVALID_SOCKET) &&
                    FD_ISSET(sip_conn.write[i], &sip_write_fds)) {
                    int connid;

                    connid = sip_tcp_fd_to_connid(sip_conn.write[i]);
                    if (connid >= 0) {
                        sip_tcp_resend(connid);
                    }
                    pending_operations--;
                }
            }
        }
    }
}