RTSMB_STATIC void rtsmb_srv_browse_check_master_browser (void) { if (rtsmb_srv_browse_election_win_count != 0) { /* An election is going on. We shouldn't mess with master browser until that is done. */ return; } if (rtsmb_srv_browse_query_master_are_querying) { if (IS_PAST (rtsmb_srv_browse_query_master_expire_base, rtsmb_srv_browse_query_master_expire_delay)) { /* The master server has not responded in a timely fashion. We must therefore force an election. */ rtsmb_srv_browse_force_election (); rtsmb_srv_browse_query_master_are_querying = FALSE; return; } } else { if (IS_PAST (rtsmb_srv_browse_query_master_expire_base, rtsmb_srv_browse_query_master_expire_delay)) { /* The master server's cache value has expired. We should remove the master server from our cache and try to find it again. This takes care of the problem of a crashed server or whatever. */ rtsmb_srv_nbns_invalidate_one_name (rtsmb_srv_nbns_get_our_group (), RTSMB_NB_NAME_TYPE_MASTER_BROWSER); } else { /* we're not querying, and the name hasn't expired, so we aren't interested anymore */ return; } } if (rtsmb_srv_nbns_is_in_name_cache (rtsmb_srv_nbns_get_our_group (), RTSMB_NB_NAME_TYPE_MASTER_BROWSER)) { /* fine, the master browser exists */ /* if this is the first time we've found it (i.e., while querying), set an expire time for it */ if (rtsmb_srv_browse_query_master_are_querying) { rtsmb_srv_browse_query_master_are_querying = FALSE; rtsmb_srv_browse_query_master_expire_base = rtp_get_system_msec(); rtsmb_srv_browse_query_master_expire_delay = RTSMB_SRV_BROWSE_MASTER_BROWSER_EXPIRE_DELAY; } } else if (!rtsmb_srv_browse_query_master_are_querying) { rtsmb_srv_nbns_start_query_for_name (rtsmb_srv_nbns_get_our_group (), RTSMB_NB_NAME_TYPE_MASTER_BROWSER); rtsmb_srv_browse_query_master_are_querying = TRUE; rtsmb_srv_browse_query_master_expire_base = rtp_get_system_msec(); rtsmb_srv_browse_query_master_expire_delay = RTSMB_NB_BCAST_RETRY_TIMEOUT * 3; /* three tries at the name is fair */ } }
RTSMB_STATIC int rtsmb_srv_browse_election_takeover (void) { RTSMB_BROWSE_SERVER_INFO info; RTSMB_DEBUG_OUTPUT_STR("rtsmb_nbds_election_takeover: Taking over master browser role\n", RTSMB_DEBUG_TYPE_ASCII); rtsmb_srv_browse_election_win_count = 0; rtsmb_srv_browse_switch_role (RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER); rtsmb_srv_browse_announcement_next_base = rtp_get_system_msec(); rtsmb_srv_browse_announcement_next_delay = 0; /* always request announcements, since our list from being a backup browser does not contain all the info a host announcement does */ /* if (rtsmb_browse_server_list_is_empty ()) */ { rtsmb_srv_browse_send_announcement_request (); } /* fill in one spot in our lists with ourselves */ rtsmb_srv_browse_our_info (&info); /* Except, change the periodicity to the maximum value so that we don't often try to remove ourselves from the list, which causes a costly comparison with the name to make sure it's not us. */ info.periodicity = 0xFFFFFFFF; rtsmb_srv_browse_update_entry (prtsmb_srv_ctx->server_table, (rtsmb_size )prtsmb_srv_ctx->server_table_size, &info); tc_strcpy (info.name, rtsmb_srv_nbns_get_our_group ()); tc_strcpy (info.comment, rtsmb_srv_nbns_get_our_name ()); info.type |= SV_TYPE_DOMAIN_ENUM; rtsmb_srv_browse_update_entry (prtsmb_srv_ctx->domain_table, (rtsmb_size )prtsmb_srv_ctx->domain_table_size, &info); /* register master browser names for our group */ rtsmb_srv_nbns_add_name (rtsmb_srv_nbns_get_our_group (), FALSE, RTSMB_NB_NAME_TYPE_MASTER_BROWSER, TRUE); rtsmb_srv_nbns_add_name (RTSMB_NB_MASTER_BROWSER_NAME, TRUE, 0x1, TRUE); /* check if we have enough backup browsers */ rtsmb_srv_browse_ensure_backup_ratio (); /* make sure that we immediately announce our domain */ rtsmb_srv_browse_master_last_domain_announcement = rtp_get_system_msec() - RTSMB_SRV_BROWSE_DOMAIN_ANNOUNCE_DELAY; return 0; }
int GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int i; rtp_srand(rtp_get_system_msec()); for (i = 0; i < sz; i++ ) { output[i] = rtp_rand() % 256; if ( (i % 8) == 7) rtp_srand(rtp_get_system_msec()); } return 0; }
void rtsmb_srv_browse_force_election (void) { int r; if (rtsmb_srv_browse_election_win_count != 0) { /* there is already an election going on */ return; } r = rtsmb_srv_browse_fill_whole_request_election (); if (r >= 0) { RTSMB_DEBUG_OUTPUT_STR("rtsmb_nbds_force_election: Forcing election.\n", RTSMB_DEBUG_TYPE_ASCII); r = rtsmb_nbds_write (prtsmb_browse_ctx->buffer, (rtsmb_size)r, rtsmb_net_get_broadcast_ip (), rtsmb_nbds_port); /* in three seconds, if we have not heard back from anybody, we should broadcast again */ rtsmb_srv_browse_election_last_send = rtp_get_system_msec(); rtsmb_srv_browse_election_win_count = 1; } }
/*---------------------------------------------------------------------------*/ void _rtp_timer_add_new_jobs (RTPTimerJob* toTimerList, RTPTimerJob* fromTimerList) { RTPTimerJob *next; RTPTimerJob *newJob; RTPTimerJob *job; long timeDifference; newJob = fromTimerList->next; while (newJob != fromTimerList) { next = newJob->next; newJob->scheduledTimeMsec += rtp_get_system_msec(); job = toTimerList->next; while (job != toTimerList) { timeDifference = (long) (job->scheduledTimeMsec - newJob->scheduledTimeMsec); if (timeDifference > 0) { break; } job = job->next; } DLLIST_REMOVE(newJob); DLLIST_INSERT_BEFORE(job, newJob); newJob->listId = RTP_TIMER_LIST_ACTIVE; newJob = next; } }
RTSMB_STATIC void rtsmb_srv_browse_switch_role (int new_role) { if (rtsmb_srv_browse_get_role () == new_role) return; switch (rtsmb_srv_browse_get_role ()) { case RTSMB_SRV_BROWSE_ROLE_BACKUP_BROWSER: rtsmb_srv_browse_backup_stop (); break; } rtsmb_srv_browse_role = new_role; switch (rtsmb_srv_browse_get_role ()) { case RTSMB_SRV_BROWSE_ROLE_BACKUP_BROWSER: rtsmb_srv_browse_backup_start (); break; /* must set up our timers for querying the master */ case RTSMB_SRV_BROWSE_ROLE_POTENTIAL_BROWSER: rtsmb_srv_browse_query_master_expire_base = rtp_get_system_msec(); rtsmb_srv_browse_query_master_expire_delay = 0; rtsmb_srv_browse_query_master_are_querying = FALSE; break; } }
long rtsmb_srv_browse_get_next_wake_timeout (void) { long rv = 0x7FFFFFFF; unsigned long current_time = rtp_get_system_msec(); rtp_sig_mutex_claim((RTP_MUTEX) prtsmb_browse_ctx->mutex); if (rtsmb_srv_browse_announcement_send) { rv = MIN (rv, (long) (rtsmb_srv_browse_announcement_next_base + rtsmb_srv_browse_announcement_next_delay - current_time)); rv = MAX (0, rv); } if (rtsmb_srv_browse_election_win_count > 0) { rv = MIN (rv, (long) (rtsmb_srv_browse_election_next_base + rtsmb_srv_browse_election_next_delay - current_time)); rv = MAX (0, rv); } if (rtsmb_srv_browse_get_role () == RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER) { rv = MIN (rv, (long) (rtsmb_srv_browse_master_last_domain_announcement + RTSMB_SRV_BROWSE_DOMAIN_ANNOUNCE_DELAY - current_time)); rv = MAX (0, rv); } rtp_sig_mutex_release((RTP_MUTEX) prtsmb_browse_ctx->mutex); return (rv == 0x7FFFFFFF) ? -1 : rv; }
RTSMB_STATIC int rtsmb_srv_browse_process_request_election (PFVOID origin, PFVOID buf, rtsmb_size size, PRTSMB_HEADER pheader) { RTSMB_NBDS_REQUEST_ELECTION request; if (rtsmb_srv_browse_read_request_election (origin, buf, size, pheader, &request) < 0) { return -1; } /* check if we won. If so, send out another request. If not, ignore */ if (rtsmb_srv_browse_have_won_election (&request)) { rtsmb_srv_browse_election_win_count ++; if (rtsmb_srv_browse_election_win_count >= 4) { rtsmb_srv_browse_election_takeover (); return 0; } rtsmb_srv_browse_election_next_base = rtp_get_system_msec(); switch (rtsmb_srv_browse_get_role ()) { case RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER: case RTSMB_SRV_BROWSE_ROLE_DOMAIN_MASTER_BROWSER: rtsmb_srv_browse_election_next_delay = 100; break; case RTSMB_SRV_BROWSE_ROLE_BACKUP_BROWSER: rtsmb_srv_browse_election_next_delay = (dword) (tc_rand () % 401 + 200); break; default: rtsmb_srv_browse_election_next_delay = (dword) (tc_rand () % 2201 + 800); break; } rtsmb_srv_browse_election_waiting_to_send = TRUE; } else { /* we've lost this election */ if (rtsmb_srv_browse_election_win_count >= 0) /* do this just once */ { if (rtsmb_srv_browse_get_role () == RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER) { rtsmb_srv_browse_switch_role (RTSMB_SRV_BROWSE_ROLE_BACKUP_BROWSER); rtsmb_srv_nbns_remove_name (rtsmb_srv_nbns_get_our_group (), RTSMB_NB_NAME_TYPE_MASTER_BROWSER); rtsmb_srv_nbns_remove_name (RTSMB_NB_MASTER_BROWSER_NAME, 0x1); } } rtsmb_srv_browse_election_win_count = -1; } return 0; }
/*---------------------------------------------------------------------------*/ void _rtp_timer_process_expired_jobs (RTPTimerJob* timerList) { RTPTimerJob *job = timerList->next; long timeDifferenceMsec; unsigned long currentMsec = rtp_get_system_msec(); void (*timerFunction) (int,void*); void* timerData; while (job != timerList) { rtpTimerNextToProcess = job->next; timeDifferenceMsec = (long) (currentMsec - job->scheduledTimeMsec); if (timeDifferenceMsec > 0) { DLLIST_REMOVE(job); if (job->repeat == RTP_TIMER_REPEAT_INFINITE) { DLLIST_INSERT_BEFORE(&rtpTimerNewList, job); job->listId = RTP_TIMER_LIST_NEW; } else { if (job->repeat > 0) { /* if this timer has more repeats left, add it to the new list */ job->repeat--; DLLIST_INSERT_BEFORE(&rtpTimerNewList, job); job->listId = RTP_TIMER_LIST_NEW; } else { DLLIST_INIT(job); job->listId = RTP_TIMER_LIST_NONE; } } if (job->timerFunction) { timerFunction = job->timerFunction; timerData = job->timerData; rtp_sig_mutex_release(rtpTimerLock); timerFunction(0, timerData); rtp_sig_mutex_claim(rtpTimerLock); } } else { break; } job = rtpTimerNextToProcess; } rtpTimerNextToProcess = 0; }
void rtsmb_srv_browse_restart_announcements (void) { rtp_sig_mutex_claim((RTP_MUTEX) prtsmb_browse_ctx->mutex); rtsmb_srv_browse_announcement_count = 0; rtsmb_srv_browse_announcement_next_base = rtp_get_system_msec(); rtsmb_srv_browse_announcement_next_delay = 0; rtp_sig_mutex_release((RTP_MUTEX) prtsmb_browse_ctx->mutex); }
// PeriodicTimerCB - Should be called once every hundred milliseconds, but longer duty cycles will be okay. extern "C" void PeriodicTimerCB(void) { HTMLEvent e; unsigned long current_tick_count; current_tick_count = rtp_get_system_msec(); if ((current_tick_count - last_timer_expiration) >= WEBCTIMERFREQ) { e.type = HTML_EVENT_TIMER; last_timer_expiration=current_tick_count; QueCopyEventForWebCFromIsr(&e); } }
RTSMB_STATIC PNET_SESSIONCTX rtsmb_srv_net_connection_open (PNET_THREAD pThread) { PNET_SESSIONCTX pNetCtx; RTP_SOCKET sock; unsigned char clientAddr[4]; int clientPort; int ipVersion; /** * Move connection to a shiny new port and socket. */ RTSMB_DEBUG_OUTPUT_STR("about to accept\n", RTSMB_DEBUG_TYPE_ASCII); if (rtp_net_accept ((RTP_SOCKET *) &sock,(RTP_SOCKET) net_ssnSock, clientAddr, &clientPort, &ipVersion) < 0) { RTSMB_DEBUG_OUTPUT_STR("rtsmb_srv_net_connection_open: accept error\n", RTSMB_DEBUG_TYPE_ASCII); return (PNET_SESSIONCTX)0; } pNetCtx = allocateSession(); RTSMB_DEBUG_OUTPUT_STR("allocateSession back\n", RTSMB_DEBUG_TYPE_ASCII); if(pNetCtx) { pNetCtx->sock = sock; RTSMB_DEBUG_OUTPUT_STR("SMBS_InitSessionCtx\n", RTSMB_DEBUG_TYPE_ASCII); pNetCtx->lastActivity = rtp_get_system_msec (); SMBS_InitSessionCtx(&(pNetCtx->smbCtx), pNetCtx->sock); RTSMB_DEBUG_OUTPUT_STR("Back SMBS_InitSessionCtx\n", RTSMB_DEBUG_TYPE_ASCII); SMBS_SetBuffers (&pNetCtx->smbCtx, pThread->inBuffer, prtsmb_srv_ctx->small_buffer_size, pThread->outBuffer, prtsmb_srv_ctx->small_buffer_size, pThread->tmpBuffer, prtsmb_srv_ctx->small_buffer_size); RTSMB_DEBUG_OUTPUT_STR ("rtsmb_srv_net_connection_open: socket ", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_DINT (pNetCtx->sock); RTSMB_DEBUG_OUTPUT_STR (" opened\n", RTSMB_DEBUG_TYPE_ASCII); return pNetCtx; } else { RTSMB_DEBUG_OUTPUT_STR("rtsmb_srv_net_connection_open: No free sessions\n", RTSMB_DEBUG_TYPE_ASCII); /* let them know we are rejecting their request */ rtsmb_srv_nbss_send_session_response (sock, FALSE); if (rtp_net_closesocket((RTP_SOCKET) sock)) { RTSMB_DEBUG_OUTPUT_STR("ERROR IN CLOSESOCKET\n", RTSMB_DEBUG_TYPE_ASCII); } return (PNET_SESSIONCTX)0; } }
RTSMB_STATIC void rtsmb_srv_browse_check_dead_servers (void) { int i; BBOOL killed_server = FALSE; unsigned long current_time; current_time = rtp_get_system_msec(); /* clear out old (3 times the periodicity) server entries */ for (i = 0; i < prtsmb_srv_ctx->server_table_size; i++) { if (prtsmb_srv_ctx->server_table[i].type) { if (IS_PAST_THIS (current_time, prtsmb_srv_ctx->server_table[i].time_received, prtsmb_srv_ctx->server_table[i].periodicity * 3) && rtsmb_strcasecmp (prtsmb_srv_ctx->server_table[i].name, rtsmb_srv_nbns_get_our_name (), CFG_RTSMB_USER_CODEPAGE)) { /* kill it */ prtsmb_srv_ctx->server_table[i].type = 0; RTSMB_DEBUG_OUTPUT_STR ("rtsmb_browse_check_dead_servers: Removing ", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_STR (prtsmb_srv_ctx->server_table[i].name, RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_STR (" from server list due to unresponsiveness.\n", RTSMB_DEBUG_TYPE_ASCII); killed_server = TRUE; } } } /* do the same for domains */ for (i = 0; i < prtsmb_srv_ctx->domain_table_size; i++) { if (prtsmb_srv_ctx->domain_table[i].type) { if (IS_PAST_THIS (current_time, prtsmb_srv_ctx->domain_table[i].time_received, prtsmb_srv_ctx->domain_table[i].periodicity * 3) && rtsmb_strcasecmp (prtsmb_srv_ctx->domain_table[i].name, rtsmb_srv_nbns_get_our_group (), CFG_RTSMB_USER_CODEPAGE)) { /* kill it */ prtsmb_srv_ctx->domain_table[i].type = 0; RTSMB_DEBUG_OUTPUT_STR ("rtsmb_browse_check_dead_servers: Removing ", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_STR (prtsmb_srv_ctx->domain_table[i].name, RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_STR (" from domain list due to unresponsiveness.\n", RTSMB_DEBUG_TYPE_ASCII); } } } if (killed_server) { /* check if we have enough backup browsers */ rtsmb_srv_browse_ensure_backup_ratio (); } }
/* prtsmb_browse_ctx->mutex must be claimed before calling this function */ void rtsmb_srv_browse_process_message (int command, PFVOID origin, PFVOID buf, rtsmb_size size, PRTSMB_HEADER pheader) { if (!rtsmb_srv_browse_announcement_send) { return; } switch (command) { case RTSMB_NBDS_COM_DOMAIN_ANNOUNCEMENT: rtsmb_srv_browse_process_domain_announcement (origin, buf, size, pheader); break; case RTSMB_NBDS_COM_LOCAL_MASTER_ANNOUNCEMENT: /* someone won a recent election */ rtsmb_srv_browse_election_win_count = 0; /* we are ready to receive election requests again */ /* intentional no-break here. we want to treat local master announcements just like host announcements */ case RTSMB_NBDS_COM_HOST_ANNOUNCEMENT: rtsmb_srv_browse_process_host_announcement (origin, buf, size, pheader); break; case RTSMB_NBDS_COM_MASTER_ANNOUNCEMENT: break; case RTSMB_NBDS_COM_ANNOUNCEMENT_REQUEST: /* send announcement */ /* send an announcement within 30 seconds */ rtsmb_srv_browse_announcement_next_base = rtp_get_system_msec(); rtsmb_srv_browse_announcement_next_delay = (dword)(tc_rand () % 30000); break; case RTSMB_NBDS_COM_REQUEST_ELECTION: /* do we win this election? */ rtsmb_srv_browse_process_request_election (origin, buf, size, pheader); break; case RTSMB_NBDS_COM_GET_BACKUP_LIST_REQUEST: if (rtsmb_srv_browse_get_role () == RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER) { rtsmb_srv_browse_process_backup_list_request (origin, buf, size, pheader); } break; case RTSMB_NBDS_COM_BECOME_BACKUP: rtsmb_srv_browse_process_become_backup (origin, buf, size, pheader); break; } }
void rtsmb_srv_browse_init (void) { rtsmb_nbds_init (); rtsmb_srv_browse_election_waiting_to_send = FALSE; rtsmb_srv_browse_election_win_count = 0; rtsmb_srv_browse_announcement_count = 0; rtsmb_srv_browse_announcement_next_base = rtp_get_system_msec(); rtsmb_srv_browse_announcement_next_delay = 0; rtsmb_srv_browse_role = RTSMB_SRV_BROWSE_ROLE_POTENTIAL_BROWSER; rtsmb_srv_browse_query_master_expire_base = rtp_get_system_msec(); rtsmb_srv_browse_query_master_expire_delay = 0; rtsmb_srv_browse_query_master_are_querying = FALSE; #if (CFG_RTSMB_SRV_BROWSE_FORCE_MASTER) rtsmb_srv_browse_force_election (); #elif (CFG_RTSMB_SRV_BROWSE_FORCE_BACKUP) rtsmb_srv_browse_switch_role (RTSMB_SRV_BROWSE_ROLE_BACKUP_BROWSER); #endif }
RTSMB_STATIC void rtsmb_srv_browse_our_info (PRTSMB_BROWSE_SERVER_INFO pinfo) { pinfo->update_count = 0; pinfo->periodicity = rtsmb_srv_browse_get_announcement_interval (); tc_strcpy (pinfo->name, rtsmb_srv_nbns_get_our_name ()); tc_strcpy (pinfo->comment, CFG_RTSMB_DEFAULT_COMMENT); pinfo->version_major = 4; pinfo->version_minor = 0; pinfo->type = rtsmb_srv_browse_get_server_type (); pinfo->browse_version_major = RTSMB_NBDS_BROWSER_VERSION_MAJOR; pinfo->browse_version_minor = RTSMB_NBDS_BROWSER_VERSION_MINOR; pinfo->signature = 0xaa55; pinfo->time_received = rtp_get_system_msec(); }
void rtp_log_open(void) { if (rtp_file_open( &debugfd, LOG_FILENAME, RTP_FILE_O_RDWR|RTP_FILE_O_CREAT |RTP_FILE_O_TRUNC|RTP_FILE_O_BINARY, RTP_FILE_S_IWRITE|RTP_FILE_S_IREAD)==0) { start_system_msec = rtp_get_system_msec (); debugfd_valid = 1; rtp_printf("Logging enabled logging to file:%s\n", LOG_FILENAME); } else { rtp_printf("Logging disabled could not open log file:%s\n", LOG_FILENAME); debugfd_valid = 0; } }
RTSMB_STATIC int rtsmb_srv_browse_process_domain_announcement (PFVOID origin, PFVOID buf, rtsmb_size size, PRTSMB_HEADER pheader) { RTSMB_NBDS_HOST_ANNOUNCEMENT host; char group_name [RTSMB_NB_NAME_SIZE + 1]; rtsmb_char master_name_rt [RTSMB_NB_NAME_SIZE + 1]; host.comment = master_name_rt; host.comment_size = RTSMB_NB_NAME_SIZE; if (rtsmb_srv_browse_read_host_announcement (origin, buf, size, pheader, &host) < 0) { return -1; } rtsmb_util_rtsmb_to_ascii (host.server_name, group_name, CFG_RTSMB_USER_CODEPAGE); if (rtsmb_srv_browse_get_role () == RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER) { RTSMB_BROWSE_SERVER_INFO info; /* if this group is our group, someone is encroaching on our responsibilities. force election to see who is really master */ if (tc_strcmp (group_name, rtsmb_srv_nbns_get_our_group ()) == 0) { rtsmb_srv_browse_force_election (); return 0; } /* search through our list and update entry */ rtsmb_util_rtsmb_to_ascii (host.server_name, info.name, CFG_RTSMB_USER_CODEPAGE); info.type = host.type; info.version_minor = host.version_minor; info.version_major = host.version_major; info.browse_version_minor = host.browse_version_major; info.browse_version_major = host.browse_version_major; info.signature = host.signature; info.update_count = host.update_count; info.periodicity = host.periodicity; rtsmb_util_rtsmb_to_ascii (host.comment, info.comment, CFG_RTSMB_USER_CODEPAGE); info.time_received = rtp_get_system_msec(); rtsmb_srv_browse_update_entry (prtsmb_srv_ctx->domain_table, (rtsmb_size )prtsmb_srv_ctx->domain_table_size, &info); } return 0; }
/*---------------------------------------------------------------------------*/ long _rtp_timer_find_msecs_to_next_timer (RTPTimerJob* timerList) { long timeout = RTP_TIMEOUT_INFINITE; RTPTimerJob *job = timerList->next; if (job != timerList) { timeout = (long) (job->scheduledTimeMsec - rtp_get_system_msec()); if (timeout < 0) { timeout = 0; } } return (timeout); }
void rtp_log_write(char *prompt, void *pData, long nBytes) { if (debugfd_valid) { unsigned long elapsed; char outbuff[256]; elapsed = rtp_get_system_msec () - start_system_msec; rtp_sprintf(outbuff,"\r\n ==<%s (t=%8d) (c=%4d) >== \r\n", (const unsigned char*) prompt,elapsed, nBytes); rtp_file_write (debugfd, (const unsigned char*) outbuff, (long) rtp_strlen(outbuff)); if (pData && nBytes > 0) { rtp_file_write (debugfd, (const unsigned char*) pData, (long) nBytes); rtp_sprintf(outbuff,"\r\n ==<===========================================>==\r\n"); rtp_file_write (debugfd, (const unsigned char*) outbuff, (long) rtp_strlen(outbuff)); } rtp_file_flush (debugfd); } }
SSDP_BOOL SSDP_ServerProcessState ( SSDPServerContext* ctx, RTP_FD_SET* readList, RTP_FD_SET* writeList, RTP_FD_SET* errList ) { SSDP_UINT32 currentTimeMsec = rtp_get_system_msec(); SSDP_CheckPendingResponses(ctx, currentTimeMsec); if (rtp_fd_isset(readList, ctx->announceSocket)) { _SSDP_ProcessOneRequest(ctx); rtp_fd_clr(readList, ctx->announceSocket); } return (0); }
RTSMB_STATIC int rtsmb_srv_browse_send_request_election (void) { int r; r = rtsmb_srv_browse_fill_whole_request_election (); if (r >= 0) { RTSMB_DEBUG_OUTPUT_STR("rtsmb_nbds_send_request_election: Sending election request.\n", RTSMB_DEBUG_TYPE_ASCII); r = rtsmb_nbds_write (prtsmb_browse_ctx->buffer, (rtsmb_size)r, rtsmb_net_get_broadcast_ip (), rtsmb_nbds_port); /* in three seconds, if we have not heard back from anybody, we should broadcast again */ rtsmb_srv_browse_election_last_send = rtp_get_system_msec(); } return r; }
SSDP_INT32 SSDP_ServerAddToSelectList ( SSDPServerContext* ctx, RTP_FD_SET* readList, RTP_FD_SET* writeList, RTP_FD_SET* errList ) { SSDP_INT32 timeout = RTP_TIMEOUT_INFINITE; /* Check the pending response list to see if any response is scheduled to be send */ if (ctx->pendingResponses.next != &ctx->pendingResponses) { SSDP_UINT32 currentTimeMsec = rtp_get_system_msec(); SSDPPendingResponse *pendingResponse = (SSDPPendingResponse *) ctx->pendingResponses.next; timeout = (SSDP_INT32) (pendingResponse->scheduledTimeMsec - currentTimeMsec); } rtp_fd_set(readList, ctx->announceSocket); return (timeout); }
HTMLEventStatus DisplayManager::DispatchEvent (HTMLEvent *pEvent) { HTMLEventStatus status; switch (pEvent->type) { case HTML_EVENT_MOUSEDOWN: case HTML_EVENT_MOUSEOVER: case HTML_EVENT_MOUSEMOVE: case HTML_EVENT_MOUSEOUT: case HTML_EVENT_MOUSEUP: case HTML_EVENT_CLICK: case HTML_EVENT_DBLCLICK: pEvent->data.position.x += mViewRect.left; pEvent->data.position.y += mViewRect.top; break; default: break; }; switch (pEvent->type) { case HTML_EVENT_KEYUP: if (!mpFocus) { mpFocus = mRoot.Get(); } if (mpFocus) { return (mpFocus->Event(pEvent)); } break; case HTML_EVENT_KEYDOWN: if (!mpFocus) { mpFocus = mRoot.Get(); } if (mpFocus) { ObjectReference<DisplayElement> focus(mpFocus); status = mpFocus->Event(pEvent); if ((status != HTML_EVENT_STATUS_HALT) && focus.Get()) { HTMLEvent e = *pEvent; e.type = HTML_EVENT_KEYPRESS; return (focus.Get()->Event(&e)); } return (status); } break; case HTML_EVENT_MOUSEDOWN: if (mpPointerOwner) { return (mpPointerOwner->Event(pEvent)); } else { DisplayElement *pElem = FindTopElement(pEvent->data.position.x, pEvent->data.position.y); if (!pElem) { pElem = mRoot.Get(); if (!pElem) { return (HTML_EVENT_STATUS_DONE); } } mpMouseDownElement = pElem; HTMLEventStatus result = pElem->Event(pEvent); if (result != HTML_EVENT_STATUS_HALT && !(pEvent->flags & HTML_EVENT_FLAG_CANCEL_SET_FOCUS)) { if (mpFocus != pElem) { DisplayElement *pNewFocus = pElem; /* Find the closest ancestor (including pElem) of pElem that is able to receive the keyboard FOCUS */ while (pNewFocus && (!(pNewFocus->mFlags & DISPLAY_FLAG_ACCEPTS_FOCUS) || (pNewFocus->mFlags & DISPLAY_FLAG_DISABLED))) { pNewFocus = pNewFocus->FocusDefault(); } if (pNewFocus && (pNewFocus != mpFocus)) { if (SetFocus(pNewFocus) == HTML_EVENT_STATUS_HALT) { return (HTML_EVENT_STATUS_HALT); } } } } return (result); } break; case HTML_EVENT_MOUSEOVER: case HTML_EVENT_MOUSEMOVE: { DisplayElement *pElem = FindTopElement(pEvent->data.position.x, pEvent->data.position.y); if (!pElem) { pElem = mRoot.Get(); if (!pElem) { return (HTML_EVENT_STATUS_DONE); } } if (pElem != mpMouseOverElement) { DisplayElement *pOld = mpMouseOverElement; mpMouseOverElement = pElem; HTMLEvent e = *pEvent; if (pOld) { e.type = HTML_EVENT_MOUSEOUT; if (pOld->Event(&e) == HTML_EVENT_STATUS_HALT) { return (HTML_EVENT_STATUS_HALT); } } // if this is a mouseover event, then we send it to pElem below if (mpMouseOverElement && pEvent->type != HTML_EVENT_MOUSEOVER) { e.type = HTML_EVENT_MOUSEOVER; if (mpMouseOverElement->Event(&e) == HTML_EVENT_STATUS_HALT) { return (HTML_EVENT_STATUS_HALT); } } return (HTML_EVENT_STATUS_CONTINUE); // April2013 - Return here, otherwise crashes below } // if the pointer is owned by an element, we shouldn't give WEBC_FALSE mouseover events // but always pass along move events (WEBC_TRUE mouseover events will be caught above). if (pEvent->type == HTML_EVENT_MOUSEMOVE) { if (mpPointerOwner) { return (mpPointerOwner->Event(pEvent)); } } if (pElem) { return (pElem->Event(pEvent)); } return (HTML_EVENT_STATUS_CONTINUE); } case HTML_EVENT_MOUSEOUT: if (mpMouseOverElement) { DisplayElement *pOld = mpMouseOverElement; mpMouseOverElement = 0; return (pOld->Event(pEvent)); } break; case HTML_EVENT_MOUSEUP: { DisplayElement *pElem; if (mpPointerOwner) { pElem = mpPointerOwner; } else { pElem = FindTopElement(pEvent->data.position.x, pEvent->data.position.y); if (!pElem) { pElem = mRoot.Get(); if (!pElem) { return (HTML_EVENT_STATUS_DONE); } } } if (pElem->Event(pEvent) == HTML_EVENT_STATUS_HALT) { return (HTML_EVENT_STATUS_HALT); } if (pElem == mpMouseDownElement) { HTMLEventStatus result; HTMLEvent e = *pEvent; e.type = HTML_EVENT_CLICK; mpMouseDownElement = 0; result = pElem->Event(&e); if (result != HTML_EVENT_STATUS_HALT) { if (mbClickTimeValid && ((rtp_get_system_msec() - miClickTime) <= WEBC_DBLCLICK_TIME)) { mbClickTimeValid = 0; e.type = HTML_EVENT_DBLCLICK; result = pElem->Event(&e); } else { mbClickTimeValid = 1; miClickTime = rtp_get_system_msec(); } } return (result); } mpMouseDownElement = 0; } break; // we don't expect to get any of these from the OS case HTML_EVENT_FOCUS: // intentional fall-through case HTML_EVENT_UNFOCUS: // intentional fall-through case HTML_EVENT_CLICK: // intentional fall-through case HTML_EVENT_DBLCLICK: // intentional fall-through case HTML_EVENT_KEYPRESS: // intentional fall-through case HTML_EVENT_LOAD: // intentional fall-through case HTML_EVENT_UNLOAD: // intentional fall-through case HTML_EVENT_SUBMIT: // intentional fall-through case HTML_EVENT_CHANGE: // intentional fall-through case HTML_EVENT_EDIT: // intentional fall-through case HTML_EVENT_RESET: // intentional fall-through default: break; } return (HTML_EVENT_STATUS_CONTINUE); }
RTSMB_STATIC int rtsmb_srv_browse_process_host_announcement (PFVOID origin, PFVOID buf, rtsmb_size size, PRTSMB_HEADER pheader) { RTSMB_NBDS_HOST_ANNOUNCEMENT host; RTSMB_BROWSE_SERVER_INFO info; rtsmb_char comment_rt [RTSMB_MAX_COMMENT_SIZE + 1]; host.comment = comment_rt; host.comment_size = RTSMB_MAX_COMMENT_SIZE; if (rtsmb_srv_browse_read_host_announcement (origin, buf, size, pheader, &host) < 0) { return -1; } if (host.opcode == RTSMB_NBDS_COM_LOCAL_MASTER_ANNOUNCEMENT) { /* cache this name of our local master browser */ rtsmb_util_rtsmb_to_ascii (host.server_name, prtsmb_srv_ctx->local_master, CFG_RTSMB_USER_CODEPAGE); } else if (host.opcode == RTSMB_NBDS_COM_HOST_ANNOUNCEMENT) { if (host.type == 0) { char server_name [RTSMB_NB_NAME_SIZE + 1]; rtsmb_util_rtsmb_to_ascii (host.server_name, server_name, CFG_RTSMB_USER_CODEPAGE); /* if the local master is shutting down, we need to force an election */ if (tc_strcmp (server_name, prtsmb_srv_ctx->local_master) == 0) { rtsmb_srv_browse_force_election (); } } } if (rtsmb_srv_browse_get_role () == RTSMB_SRV_BROWSE_ROLE_MASTER_BROWSER) { /* if the type indicates a master browser, someone is encroaching on our responsibilities. Force election to see who is really master */ if (ON (host.type, SV_TYPE_MASTER_BROWSER)) { rtsmb_srv_browse_force_election (); return 0; } /* search through our list and update entry */ rtsmb_util_rtsmb_to_ascii (host.server_name, info.name, CFG_RTSMB_USER_CODEPAGE); info.type = host.type; info.version_minor = host.version_minor; info.version_major = host.version_major; info.browse_version_minor = host.browse_version_major; info.browse_version_major = host.browse_version_major; info.signature = host.signature; info.update_count = host.update_count; info.periodicity = host.periodicity; rtsmb_util_rtsmb_to_ascii (host.comment, info.comment, CFG_RTSMB_USER_CODEPAGE); info.time_received = rtp_get_system_msec(); rtsmb_srv_browse_update_entry (prtsmb_srv_ctx->server_table, (rtsmb_size )prtsmb_srv_ctx->server_table_size, &info); /* check if we have enough backup browsers */ rtsmb_srv_browse_ensure_backup_ratio (); } return 0; }
/* ============== ============== */ void rtsmb_srv_net_init (void) { RTSMB_STATIC PNET_THREAD tempThread; #if (CFG_RTSMB_PRINT_SIZES) char buffer[128]; rtp_sprintf (buffer, "net thread: %i\n", sizeof (NET_THREAD_T)); tm_puts (buffer); #endif #if INCLUDE_RTSMB_DC next_pdc_find = rtp_get_system_msec () + rtsmb_srv_net_pdc_next_interval (); #endif /** * You will note that we consistently use the term 'thread' to refer to the 'mainThread.' * In fact, it is not a full blown thread, but is only treated the same, for coding simplicity * purposes. This first thread always runs in the same thread/process as the caller of our API * functions. If CFG_RTSMB_MAX_THREADS is 0, no threads will ever be created. */ tempThread = rtsmb_srv_net_thread_new (); /* this will succeed because there is at least one thread free at start */ if (!tempThread) { RTSMB_DEBUG_OUTPUT_STR("rtsmb_srv_net_init: Error -- could not allocate main pseudo-thread.\n", RTSMB_DEBUG_TYPE_ASCII); return; } mainThread = tempThread; rtsmb_srv_net_thread_init (mainThread, 0); /* -------------------- */ /* get the three major sockets */ /* Name Service Datagram Socket */ if (rtsmb_net_socket_new (&net_nsSock, rtsmb_nbns_port, FALSE) < 0) { rtp_printf(("Could not allocate Name & Datagram service socket\n")); } /* SSN Reliable Socket */ #ifdef RTSMB_ALLOW_SMB_OVER_TCP if (rtsmb_net_socket_new (&net_ssnSock, rtsmb_nbss_direct_port, TRUE) < 0) { rtp_printf(("Could not allocate Name & Datagram service socket\n")); } #else if (rtsmb_net_socket_new (&net_ssnSock, rtsmb_nbss_port, TRUE) < 0) { rtp_printf (("Could not allocate SSN Reliable socket\n")); } #endif if (rtp_net_listen ((RTP_SOCKET) net_ssnSock, prtsmb_srv_ctx->max_sessions) != 0) { RTSMB_DEBUG_OUTPUT_STR("Error occurred while trying to listen on SSN Reliable socket.\n", RTSMB_DEBUG_TYPE_ASCII); } if (rtp_net_setbroadcast((RTP_SOCKET) net_nsSock, 1) < 0) { RTSMB_DEBUG_OUTPUT_STR("Error occurred while trying to set broadcast on Name & Datagram service socket\n", RTSMB_DEBUG_TYPE_ASCII); } }
RTSMB_STATIC BBOOL rtsmb_srv_net_session_cycle (PNET_SESSIONCTX *session, int ready) { BBOOL isDead = FALSE; BBOOL rv = TRUE; claimSession (*session); /* keep session alive while we do stuff */ switch ((*session)->smbCtx.state) { case BROWSE_MUTEX: case BROWSE_SENT: case WAIT_ON_PDC_NAME: case WAIT_ON_PDC_IP: case FINISH_NEGOTIATE: case FAIL_NEGOTIATE: (*session)->lastActivity = rtp_get_system_msec (); break; default: break; } /* handle special state cases here, potentially skipping netbios layer */ switch ((*session)->smbCtx.state) { #if (INCLUDE_RTSMB_DC) case WAIT_ON_PDC_NAME: SMBS_StateWaitOnPDCName (&(*session)->smbCtx); break; case WAIT_ON_PDC_IP: SMBS_StateWaitOnPDCIP (&(*session)->smbCtx); break; case FINISH_NEGOTIATE: case FAIL_NEGOTIATE: SMBS_StateContinueNegotiate (&(*session)->smbCtx); break; #endif case BROWSE_MUTEX: case BROWSE_SENT: case BROWSE_FINISH: case BROWSE_FAIL: rtsmb_srv_browse_finish_server_enum (&(*session)->smbCtx); break; case READING: case WRITING_RAW_READING: /* finish reading what we started. */ SMBS_ProcSMBPacket (&(*session)->smbCtx, (*session)->smbCtx.in_packet_size - (*session)->smbCtx.current_body_size); break; default: if (ready) { (*session)->lastActivity = rtp_get_system_msec (); if (rtsmb_srv_nbss_process_packet (&(*session)->smbCtx) == FALSE) { isDead = TRUE; } } else { /*check for time out */ if(IS_PAST ((*session)->lastActivity, RTSMB_NBNS_KEEP_ALIVE_TIMEOUT)) { RTSMB_DEBUG_OUTPUT_STR ("rtsmb_srv_net_session_cycle: Connection timed out on socket ", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_DINT ((*session)->sock); RTSMB_DEBUG_OUTPUT_STR ("\n", RTSMB_DEBUG_TYPE_ASCII); RTSMB_DEBUG_OUTPUT_STR ("rtsmb_srv_net_session_cycle: Resetting timer, not killing the socket\n", RTSMB_DEBUG_TYPE_ASCII); (*session)->lastActivity = rtp_get_system_msec (); /* isDead = TRUE; */ } } break; } if (isDead) { rtsmb_srv_net_connection_close (*session); rv = FALSE; } releaseSession (*session); if (isDead) { *session = (PNET_SESSIONCTX)0; } return rv; }
RTSMB_STATIC BBOOL rtsmb_srv_net_thread_cycle (PNET_THREAD pThread, RTP_SOCKET *readList, int readListSize) { PNET_SESSIONCTX *session; int i,n; /** * The reason we wait here to seed tc_rand() is so that the seed value has * some degree of randomness to it. This gets called the first time there * is network traffic on this thread's sockets, so the network is our * only source of randomness. Not very good, but its the best we have. * * We could use time (), and you are welcome to use that instead, but I * am under the impression that not all embedded compilers support time.h. */ if (!pThread->srand_is_initialized) { tc_srand ((unsigned int) rtp_get_system_msec ()); pThread->srand_is_initialized = TRUE; } /** * Now we run the sessions we are responsible for. */ for(i = 0; i < (int)pThread->numSessions; i++) { int current_session_index = (i + (int)pThread->index) % (int)pThread->numSessions; SMBS_SESSION_STATE starting_state; /* Shouldn't run if a blocking session exists and we aren't it. */ if (pThread->blocking_session != -1 && pThread->blocking_session != current_session_index) { continue; } session = &pThread->sessionList[current_session_index]; starting_state = (*session)->smbCtx.state; for (n = 0; n < readListSize; n++) { if (readList[n] == (*session)->sock) { rtsmb_srv_net_session_cycle (session, TRUE); break; } } if (n == readListSize) { rtsmb_srv_net_session_cycle (session, FALSE); } /* Warning: at this point, (*session) may be NULL */ /* if we changed states, and we are changing away from idle, we should block on this session. If we are changing to idle, we should stop blocking on this session */ if ((*session) && starting_state != (*session)->smbCtx.state) { if (starting_state == IDLE) { pThread->blocking_session = current_session_index; } else if ((*session)->smbCtx.state == IDLE) { pThread->blocking_session = -1; } } else if (!(*session)) { /* dead session. clear block if this held it */ if (pThread->blocking_session == current_session_index) { pThread->blocking_session = -1; } } } rtsmb_srv_net_thread_condense_sessions (pThread); if (pThread->numSessions) { /* mix it up a bit, in case a session at the front is hogging time */ pThread->index = ((dword) tc_rand () % pThread->numSessions); return TRUE; } else { return FALSE; } }
/*----------------------------------------------------------------------* rtp_get_system_sec *----------------------------------------------------------------------*/ unsigned long rtp_get_system_sec () { NATIVE_PROFILE_PAL_NETWORK(); return((unsigned long) (rtp_get_system_msec() /1000)); }
void rtsmb_srv_net_cycle (long timeout) { RTP_SOCKET readList[256]; int len; word i; if (!mainThread) { return; } /** * Build the list of sockets to poll, consisting of the * name service socket, session service socket, and * sessions' sockets we are handling. */ len = 0; readList[len++] = net_nsSock; /* Name Service Socket */ readList[len++] = rtsmb_nbds_get_socket (); /* Datagram Service Socket */ readList[len++] = net_ssnSock; /* Session Service Socket */ for (i = 0; i < mainThread->numSessions && len < 256; i++) { readList[len++] = mainThread->sessionList[i]->sock; } len = rtsmb_netport_select_n_for_read (readList, len, timeout); /** * Handle name requests, etc. */ for (i = 0; i < len; i++) { if (readList[i] == net_nsSock) { byte datagram[RTSMB_NB_MAX_DATAGRAM_SIZE]; /*process datagram */ rtsmb_net_read_datagram (net_nsSock, datagram, RTSMB_NB_MAX_DATAGRAM_SIZE, net_lastRemoteHost_ip, &net_lastRemoteHost_port); /* only handle datagrams that don't originate from us */ if (tc_memcmp (net_lastRemoteHost_ip, rtsmb_srv_net_get_host_ip (), 4) != 0) { rtsmb_srv_nbns_process_packet (datagram, RTSMB_NB_MAX_DATAGRAM_SIZE); } } /** * If a new session has arrived and we have free threads, give half our * sessions to them. */ else if (readList[i] == net_ssnSock) { RTSMB_DEBUG_OUTPUT_STR("A client is requesting a connection.\n", RTSMB_DEBUG_TYPE_ASCII); rtsmb_srv_net_thread_new_session (mainThread); } } /* handle sessions we own */ rtsmb_srv_net_thread_cycle (mainThread, readList, len); #if INCLUDE_RTSMB_DC /* now see if we need to query for the pdc again */ if (!MS_IsKnownPDCName () && next_pdc_find <= rtp_get_system_msec ()) { MS_SendPDCQuery (); next_pdc_find = next_pdc_find + rtsmb_srv_net_pdc_next_interval (); } #endif }