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); }
// 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; }
/** * 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--; } } } } }