int load_add_interval(Load *load, int interval) { int i; struct load_entry *entry; if (load == NULL) return -1; gw_rwlock_wrlock(load->lock); /* first look if we have equal interval added already */ for (i = 0; i < load->len; i++) { if (load->entries[i]->interval == interval) { gw_rwlock_unlock(load->lock); return -1; } } /* so no equal interval there, add new one */ entry = gw_malloc(sizeof(struct load_entry)); entry->prev = entry->curr = 0.0; entry->interval = interval; entry->dirty = 1; time(&entry->last); load->entries = gw_realloc(load->entries, sizeof(struct load*) * (load->len + 1)); load->entries[load->len] = entry; load->len++; gw_rwlock_unlock(load->lock); return 0; }
void load_increase_with(Load *load, unsigned long value) { time_t now; int i; if (load == NULL) return; gw_rwlock_wrlock(load->lock); time(&now); for (i = 0; i < load->len; i++) { struct load_entry *entry = load->entries[i]; /* check for special case, load over whole live time */ if (entry->interval != -1 && now >= entry->last + entry->interval) { /* rotate */ entry->curr /= entry->interval; if (entry->prev > 0) entry->prev = (2*entry->curr + entry->prev)/3; else entry->prev = entry->curr; entry->last = now; entry->curr = 0.0; entry->dirty = 0; } entry->curr += value; } gw_rwlock_unlock(load->lock); }
void log_close_all(void) { /* * Writer lock. */ gw_rwlock_wrlock(&rwlock); while (num_logfiles > 0) { --num_logfiles; if (logfiles[num_logfiles].file != stderr && logfiles[num_logfiles].file != NULL) fclose(logfiles[num_logfiles].file); logfiles[num_logfiles].file = NULL; } /* * Unlock writer. */ gw_rwlock_unlock(&rwlock); /* close syslog if used */ if (dosyslog) { closelog(); dosyslog = 0; } }
int log_open(char *filename, int level, enum excl_state excl) { FILE *f = NULL; int i; gw_rwlock_wrlock(&rwlock); if (num_logfiles == MAX_LOGFILES) { gw_rwlock_unlock(&rwlock); error(0, "Too many log files already open, not adding `%s'", filename); return -1; } if (strlen(filename) > FILENAME_MAX) { gw_rwlock_unlock(&rwlock); error(0, "Log filename too long: `%s'.", filename); return -1; } /* * Check if the file is already opened for logging. * If there is an open file, then assign the file descriptor * that is already existing for this log file. */ for (i = 0; i < num_logfiles && f == NULL; ++i) { if (strcmp(logfiles[i].filename, filename) == 0) f = logfiles[i].file; } /* if not previously opened, then open it now */ if (f == NULL) { f = fopen(filename, "a"); if (f == NULL) { gw_rwlock_unlock(&rwlock); error(errno, "Couldn't open logfile `%s'.", filename); return -1; } } logfiles[num_logfiles].file = f; logfiles[num_logfiles].minimum_output_level = level; logfiles[num_logfiles].exclusive = excl; strcpy(logfiles[num_logfiles].filename, filename); ++num_logfiles; i = num_logfiles - 1; gw_rwlock_unlock(&rwlock); info(0, "Added logfile `%s' with level `%d'.", filename, level); return i; }
void smpp_listener_auth_failed(SMPPServer *smpp_server, Octstr *ip) { if (octstr_len(smpp_server->ip_blocklist_exempt_ips) && (octstr_search(smpp_server->ip_blocklist_exempt_ips, ip, 0) > -1)) { debug("smpp.listener.auth.failed", 0, "IP address %s is exempt from the IP block list", octstr_get_cstr(ip)); return; } gw_rwlock_wrlock(smpp_server->ip_blocklist_lock); SMPPBlockedIp *smpp_blocked_ip = dict_get(smpp_server->ip_blocklist, ip); if(smpp_blocked_ip == NULL) { smpp_blocked_ip = smpp_blocked_ip_create(); dict_put(smpp_server->ip_blocklist, ip, smpp_blocked_ip); } smpp_blocked_ip->attempts++; smpp_blocked_ip->time_blocked = time(NULL); debug("smpp.listener.auth.failed", 0, "IP address %s, attempts %ld have failed", octstr_get_cstr(ip), smpp_blocked_ip->attempts); gw_rwlock_unlock(smpp_server->ip_blocklist_lock); }
void smpp_route_rebuild_database(SMPPServer *smpp_server) { info(0, "Rebuilding database routes"); SMPPRouting *smpp_routing = smpp_server->routing; List *inbound_routes = smpp_database_get_routes(smpp_server, SMPP_ROUTE_DIRECTION_INBOUND, NULL); /* Only inbound are built, outbound are built when ESME's connect */ List *old_inbound; Dict *old_outbound; gw_rwlock_wrlock(smpp_routing->lock); old_inbound = smpp_routing->inbound_routes; old_outbound = smpp_routing->outbound_routes; smpp_routing->inbound_routes = inbound_routes; smpp_routing->outbound_routes = dict_create(1024, (void(*)(void *))smpp_outbound_routes_destroy); /* Just reset, they will repopulate on their own */ gw_rwlock_unlock(smpp_routing->lock); gwlist_destroy(old_inbound, (void(*)(void *))smpp_route_destroy); dict_destroy(old_outbound); }
void log_reopen(void) { int i, j, found; /* * Writer lock. */ gw_rwlock_wrlock(&rwlock); for (i = 0; i < num_logfiles; ++i) { if (logfiles[i].file != stderr) { found = 0; /* * Reverse seek for allready reopened logfile. * If we find a previous file descriptor for the same file * name, then don't reopen that duplicate, but assign the * file pointer to it. */ for (j = i-1; j >= 0 && found == 0; j--) { if (strcmp(logfiles[i].filename, logfiles[j].filename) == 0) { logfiles[i].file = logfiles[j].file; found = 1; } } if (found) continue; if (logfiles[i].file != NULL) fclose(logfiles[i].file); logfiles[i].file = fopen(logfiles[i].filename, "a"); if (logfiles[i].file == NULL) { error(errno, "Couldn't re-open logfile `%s'.", logfiles[i].filename); } } } /* * Unlock writer. */ gw_rwlock_unlock(&rwlock); }
static void run_smsbox(void *arg) { Boxc *newconn; long sender; Msg *msg; List *keys; Octstr *key; gwlist_add_producer(flow_threads); newconn = arg; newconn->incoming = gwlist_create(); gwlist_add_producer(newconn->incoming); newconn->retry = incoming_sms; newconn->outgoing = outgoing_sms; newconn->sent = dict_create(smsbox_max_pending, NULL); newconn->pending = semaphore_create(smsbox_max_pending); sender = gwthread_create(boxc_sender, newconn); if (sender == -1) { error(0, "Failed to start a new thread, disconnecting client <%s>", octstr_get_cstr(newconn->client_ip)); goto cleanup; } /* * We register newconn in the smsbox_list here but mark newconn as routable * after identification or first message received from smsbox. So we can avoid * a race condition for routable smsboxes (otherwise between startup and * registration we will forward some messages to smsbox). */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_append(smsbox_list, newconn); gw_rwlock_unlock(smsbox_list_rwlock); gwlist_add_producer(newconn->outgoing); boxc_receiver(newconn); gwlist_remove_producer(newconn->outgoing); /* remove us from smsbox routing list */ gw_rwlock_wrlock(smsbox_list_rwlock); gwlist_delete_equal(smsbox_list, newconn); if (newconn->boxc_id) { dict_remove(smsbox_by_id, newconn->boxc_id); } gw_rwlock_unlock(smsbox_list_rwlock); /* * check if we in the shutdown phase and sms dequeueing thread * has removed the producer already */ if (gwlist_producer_count(newconn->incoming) > 0) gwlist_remove_producer(newconn->incoming); /* check if we are still waiting for ack's and semaphore locked */ if (dict_key_count(newconn->sent) >= smsbox_max_pending) semaphore_up(newconn->pending); /* allow sender to go down */ gwthread_join(sender); /* put not acked msgs into incoming queue */ keys = dict_keys(newconn->sent); while((key = gwlist_extract_first(keys)) != NULL) { msg = dict_remove(newconn->sent, key); gwlist_produce(incoming_sms, msg); octstr_destroy(key); } gw_assert(gwlist_len(keys) == 0); gwlist_destroy(keys, octstr_destroy_item); /* clear our send queue */ while((msg = gwlist_extract_first(newconn->incoming)) != NULL) { gwlist_produce(incoming_sms, msg); } cleanup: gw_assert(gwlist_len(newconn->incoming) == 0); gwlist_destroy(newconn->incoming, NULL); gw_assert(dict_key_count(newconn->sent) == 0); dict_destroy(newconn->sent); semaphore_destroy(newconn->pending); boxc_destroy(newconn); /* wakeup the dequeueing thread */ gwthread_wakeup(sms_dequeue_thread); gwlist_remove_producer(flow_threads); }
void smpp_route_message_database(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, int result, double cost), void *context) { SMPPRouting *smpp_routing = smpp_server->routing; List *routes; long i, num_routes; int found = 0; SMPPRoute *route; gw_rwlock_rdlock(smpp_routing->lock); if(msg_type(msg) == sms) { /* we can only route sms's */ if((direction == SMPP_ROUTE_DIRECTION_OUTBOUND) && octstr_len(system_id)) { /* Look for our ESME routes */ gw_rwlock_wrlock(smpp_routing->outbound_lock); routes = dict_get(smpp_routing->outbound_routes, system_id); if(!routes) { routes = smpp_database_get_routes(smpp_server, direction, system_id); dict_put(smpp_routing->outbound_routes, system_id, routes); } gw_rwlock_unlock(smpp_routing->outbound_lock); num_routes = gwlist_len(routes); for(i=0;i<num_routes;i++) { route = gwlist_get(routes, i); found = gw_regex_match_pre(route->regex, msg->sms.receiver); if(found) { break; } } if(found) { octstr_destroy(msg->sms.smsc_id); msg->sms.smsc_id = octstr_duplicate(route->smsc_id); debug("smpp.route.message.database", 0, "SMPP[%s] Found outbound route for %s towards %s", octstr_get_cstr(system_id), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.smsc_id)); callback(context, 1, route->cost); } else { callback(context, 0, 0); } } else if((direction == SMPP_ROUTE_DIRECTION_INBOUND) && octstr_len(smsc_id)) { routes = smpp_routing->inbound_routes; num_routes = gwlist_len(routes); for(i=0;i<num_routes;i++) { route = gwlist_get(routes, i); found = gw_regex_match_pre(route->regex, msg->sms.receiver); if(found) { break; } } if(found) { octstr_destroy(msg->sms.service); msg->sms.service = octstr_duplicate(route->system_id); debug("smpp.route.message.database", 0, "SMPP[%s] Found inbound route for %s from %s", octstr_get_cstr(route->system_id), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(smsc_id)); callback(context, 1, route->cost); } else { callback(context, 0, 0); } } else { callback(context, 0, 0); } } else { callback(context, 0, 0); } gw_rwlock_unlock(smpp_routing->lock); }
int log_open(char *filename, int level, enum excl_state excl, char *do_rotatelog) { FILE *f = NULL; int i; gw_rwlock_wrlock(&rwlock); rotatelog = gw_strdup(do_rotatelog); if (num_logfiles == MAX_LOGFILES) { gw_rwlock_unlock(&rwlock); error(0, "Too many log files already open, not adding `%s'", filename); return -1; } if (strlen(filename) > FILENAME_MAX) { gw_rwlock_unlock(&rwlock); error(0, "Log filename too long: `%s'.", filename); return -1; } //if (rotate_logfile == NEVER && rotatelog && *rotatelog) { if (rotatelog && *rotatelog) { if (strcmp(rotatelog, "daily") == 0) rotate_logfile = DAILY; else if (strcmp(rotatelog, "weekly") == 0) rotate_logfile = WEEKLY; else if (strcmp(rotatelog, "monthly") == 0) rotate_logfile = MONTHLY; } /* * Check if the file is already opened for logging. * If there is an open file, then assign the file descriptor * that is already existing for this log file. */ for (i = 0; i < num_logfiles && f == NULL; ++i) { if (strcmp(logfiles[i].filename, filename) == 0) f = logfiles[i].file; } /* if not previously opened, then open it now */ if (f == NULL) { f = fopen(filename, "a"); if (f == NULL) { gw_rwlock_unlock(&rwlock); error(errno, "Couldn't open logfile `%s'.", filename); return -1; } } logfiles[num_logfiles].file = f; logfiles[num_logfiles].minimum_output_level = level; logfiles[num_logfiles].exclusive = excl; strcpy(logfiles[num_logfiles].filename, filename); ++num_logfiles; i = num_logfiles - 1; gw_rwlock_unlock(&rwlock); info(0, "Added logfile `%s' with level `%d'. Log rotation: %s. %d.", filename, level, rotatelog ? rotatelog : "never", rotate_logfile); return i; }