int init_lru_cache(struct LruCache *cache, u_int32_t max_size) { traceLRU = readOnlyGlobals.enable_debug; if(unlikely(traceLRU)) traceEvent(TRACE_NORMAL, "%s(max_size=%u)", __FUNCTION__, max_size); cache->max_cache_node_len = 4; cache->hash_size = max_size/cache->max_cache_node_len; #ifdef FULL_STATS cache->mem_size += cache->hash_size*sizeof(struct LruCacheEntry*); #endif if((cache->hash = (struct LruCacheEntry**)calloc(cache->hash_size, sizeof(struct LruCacheEntry*))) == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); return(-1); } #ifdef FULL_STATS cache->mem_size += cache->hash_size*sizeof(u_int32_t); #endif if((cache->current_hash_size = (u_int32_t*)calloc(cache->hash_size, sizeof(u_int32_t))) == NULL) { traceEvent(TRACE_ERROR, "Not enough memory?"); return(-1); } pthread_rwlock_init(&cache->lruLock, NULL); return(0); }
SOCKET open_socket(int local_port, int bind_any) { SOCKET sock_fd; struct sockaddr_in local_address; int sockopt = 1; if((sock_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { traceEvent(TRACE_ERROR, "Unable to create socket [%s][%d]\n", strerror(errno), sock_fd); return(-1); } #ifndef WIN32 /* fcntl(sock_fd, F_SETFL, O_NONBLOCK); */ #endif setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); memset(&local_address, 0, sizeof(local_address)); local_address.sin_family = AF_INET; local_address.sin_port = htons(local_port); local_address.sin_addr.s_addr = htonl(bind_any?INADDR_ANY:INADDR_LOOPBACK); if(bind(sock_fd, (struct sockaddr*) &local_address, sizeof(local_address)) == -1) { traceEvent(TRACE_ERROR, "Bind error [%s]\n", strerror(errno)); return(-1); } return(sock_fd); }
static void* redisLocalServerLoop(void* notUsed) { traceEvent(TRACE_NORMAL, "[Redis Server] %s() started", __FUNCTION__); readOnlyGlobals.redis.local_server_running = 0; while(!readWriteGlobals->shutdownInProgress) { fd_set mask; FD_ZERO(&mask); FD_SET(readOnlyGlobals.redis.local_server_socket, &mask); if(select(readOnlyGlobals.redis.local_server_socket+1, &mask, 0, 0, NULL) > 0) { struct sockaddr_in from; int rx_sock, from_len, rc; char aChar; rx_sock = accept(readOnlyGlobals.redis.local_server_socket, (struct sockaddr*)&from, (socklen_t*)&from_len); if((rx_sock < 0) || (errno != 0)) { traceEvent(TRACE_ERROR, "Unable to accept connection [%s/%d]", strerror(errno), errno); } traceEvent(TRACE_NORMAL, "[Redis Server] New client connected [socket %d]", rx_sock); handleClient(rx_sock); close(rx_sock); } } readOnlyGlobals.redis.local_server_running = 1; return(NULL); }
void log_SNM_INFO( const n2n_SNM_INFO_t *info ) { int i; n2n_sock_str_t sockbuf; traceEvent( TRACE_DEBUG, "INFO Supernodes=%d Communities=%d", info->sn_num, info->comm_num ); if (info->sn_ptr) { for(i = 0; i < info->sn_num; i++) { traceEvent( TRACE_DEBUG, "\t[S%d] %s", i, sock_to_cstr(sockbuf, &info->sn_ptr[i]) ); } } if (info->comm_ptr) { for(i = 0; i < info->comm_num; i++) { traceEvent( TRACE_DEBUG, "\t[C%d] len=%d name=%s", i, info->comm_ptr[i].size, (info->comm_ptr[i].size > 0) ? (const char *) info->comm_ptr[i].name : "" ); } } }
char* getCacheDataStrKey(const char *prefix, u_int16_t id, const char *key) { #ifdef HAVE_REDIS char *ret = NULL; redisReply *reply; if(readOnlyGlobals.redis.read_context) { pthread_rwlock_wrlock(&readOnlyGlobals.redis.lock_get); if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_NORMAL, "[Redis] GET %s%s", prefix, key); reply = redisCommand(readOnlyGlobals.redis.read_context, "GET %s%s", prefix, key); readWriteGlobals->redis.numGetCommands[id]++; pthread_rwlock_unlock(&readOnlyGlobals.redis.lock_get); if(reply) { if(reply->str) { ret = strdup(reply->str); if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_INFO, "[Redis] %s(%u)=%s", __FUNCTION__, key, ret); } freeReplyObject(reply); } } return(ret); #else return(NULL); #endif }
void getCacheDataNumKeyTwin(const char *prefix, u_int16_t id, const u_int32_t key1, const u_int32_t key2, char **rsp1, char **rsp2) { #ifdef HAVE_REDIS redisReply *reply; if(readOnlyGlobals.redis.read_context) { pthread_rwlock_wrlock(&readOnlyGlobals.redis.lock_get); if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_NORMAL, "[Redis] MGET %s%u %s%u", prefix, key1, prefix, key2); reply = redisCommand(readOnlyGlobals.redis.read_context, "MGET %s%u %s%u", prefix, key1, prefix, key2); readWriteGlobals->redis.numGetCommands[id]++; pthread_rwlock_unlock(&readOnlyGlobals.redis.lock_get); if(reply) { if(reply->element == NULL) *rsp1 = *rsp2 = NULL; else { *rsp1 = reply->element[0]->str ? strdup(reply->element[0]->str) : NULL; *rsp2 = reply->element[1]->str ? strdup(reply->element[1]->str) : NULL; } if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_NORMAL, "[Redis] %s(%u, %u)=(%s, %s)", __FUNCTION__, key1, key2, *rsp1 ? *rsp1 : "", *rsp2 ? *rsp2 : ""); freeReplyObject(reply); } } #endif }
/* Function called when the shutdown_reflector is started */ void shutdown_reflector() { u_int32_t tot_sent = 0; int i; if(!shutting_down) { shutting_down = 1; traceLevel = 6; traceEvent(TRACE_INFO, "Shutting down..."); shutdown_reflector(in_sock, SHUT_RDWR); close(in_sock); traceEvent(TRACE_INFO, "Leaving..."); close(out_sock); } traceEvent(TRACE_INFO, "Received [%u flow packets]", num_rcvd_flows); for(i=0; i<num_nf_collectors; i++) { char ebuf[64]; traceEvent(TRACE_INFO, "Collector %s: forwarded %u flows", intoaV4(ntohl(nf_collectors[i].addr.sin_addr.s_addr), ebuf, sizeof(ebuf)), nf_collectors[i].num_pkts_sent); tot_sent += nf_collectors[i].num_pkts_sent; } traceEvent(TRACE_INFO, "Forwarded [%u flows][%u discarded for missing collector]", tot_sent, unforwarded_as_no_available_collector); exit(0); }
static void trim_subhash(struct LruCache *cache, u_int32_t hash_id) { if(unlikely(traceLRU)) traceEvent(TRACE_NORMAL, "%s()", __FUNCTION__); if(cache->current_hash_size[hash_id] >= cache->max_cache_node_len) { struct LruCacheEntry *head = cache->hash[hash_id], *prev = NULL; /* Find the last entry and remove it */ while(head->next != NULL) { prev = head; head = head->next; } if(prev) { prev->next = head->next; free_lru_cache_entry(cache, head); free(head); #ifdef FULL_STATS cache->mem_size -= sizeof(struct LruCacheEntry); #endif cache->current_hash_size[hash_id]--; } else traceEvent(TRACE_ERROR, "Internal error in %s()", __FUNCTION__); } }
/* UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things. -- Doug Gwyn */ static void maximize_socket_buffer(int sock_fd, int buf_type) { int i, rcv_buffsize_base, rcv_buffsize, max_buf_size = 1024 * 2 * 1024 /* 2 MB */, debug = 0; socklen_t len = sizeof(rcv_buffsize_base); if(getsockopt(sock_fd, SOL_SOCKET, buf_type, &rcv_buffsize_base, &len) < 0) { traceEvent(TRACE_ERROR, "Unable to read socket receiver buffer size [%s]", strerror(errno)); return; } else { if(debug) traceEvent(TRACE_INFO, "Default socket %s buffer size is %d", buf_type == SO_RCVBUF ? "receive" : "send", rcv_buffsize_base); } for(i=2;; i++) { rcv_buffsize = i * rcv_buffsize_base; if(rcv_buffsize > max_buf_size) break; if(setsockopt(sock_fd, SOL_SOCKET, buf_type, &rcv_buffsize, sizeof(rcv_buffsize)) < 0) { if(debug) traceEvent(TRACE_ERROR, "Unable to set socket %s buffer size [%s]", buf_type == SO_RCVBUF ? "receive" : "send", strerror(errno)); break; } else if(debug) traceEvent(TRACE_INFO, "%s socket buffer size set %d", buf_type == SO_RCVBUF ? "Receive" : "Send", rcv_buffsize); } }
/** The twofish packet format consists of: * * - a 8-bit twofish encoding version in clear text * - a 32-bit SA number in clear text * - ciphertext encrypted from a 32-bit nonce followed by the payload. * * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] * |<------ encrypted ------>| */ static int transop_decode_twofish( ntvl_trans_op_t * arg, uint8_t * outbuf, size_t out_len, const uint8_t * inbuf, size_t in_len ) { int len=0; transop_tf_t * priv = (transop_tf_t *)arg->priv; uint8_t assembly[NTVL_PKT_BUF_SIZE]; if ( ( (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)) <= NTVL_PKT_BUF_SIZE ) /* Cipher text fits in assembly */ && (in_len >= (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_NONCE_SIZE) ) ) { /* Has at least version, SA and nonce */ ntvl_sa_t sa_rx; ssize_t sa_idx=-1; size_t rem=in_len; size_t idx=0; uint8_t tf_enc_ver=0; /* Get the encoding version to make sure it is supported */ decode_uint8( &tf_enc_ver, inbuf, &rem, &idx ); if ( NTVL_TWOFISH_TRANSFORM_VERSION == tf_enc_ver ) { /* Get the SA number and make sure we are decrypting with the right one. */ decode_uint32( &sa_rx, inbuf, &rem, &idx ); sa_idx = twofish_find_sa(priv, sa_rx); if ( sa_idx >= 0 ) { sa_twofish_t * sa = &(priv->sa[sa_idx]); traceEvent( TRACE_DEBUG, "decode_twofish %lu with SA %lu.", in_len, sa_rx, sa->sa_id ); len = TwoFishDecryptRaw( (void *)(inbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE), assembly, /* destination */ (in_len - (TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE)), sa->dec_tf); if ( len > 0 ) { /* Step over 4-byte random nonce value */ len -= TRANSOP_TF_NONCE_SIZE; /* size of ethernet packet */ memcpy( outbuf, assembly + TRANSOP_TF_NONCE_SIZE, len ); } else traceEvent( TRACE_ERROR, "decode_twofish decryption failed." ); } else { /* Wrong security association; drop the packet as it is undecodable. */ traceEvent( TRACE_ERROR, "decode_twofish SA number %lu not found.", sa_rx ); /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ } } else { /* Wrong security association; drop the packet as it is undecodable. */ traceEvent( TRACE_ERROR, "decode_twofish unsupported twofish version %u.", tf_enc_ver ); /* REVISIT: should be able to load a new SA at this point to complete the decoding. */ } } else traceEvent( TRACE_ERROR, "decode_twofish inbuf wrong size (%ul) to decrypt.", in_len ); return len; }
static ntvl_tostat_t transop_tick_twofish( ntvl_trans_op_t * arg, time_t now ) { transop_tf_t * priv = (transop_tf_t *)arg->priv; size_t i; int found=0; ntvl_tostat_t r; memset( &r, 0, sizeof(r) ); traceEvent( TRACE_DEBUG, "transop_tf tick num_sa=%u", priv->num_sa ); for ( i=0; i < priv->num_sa; ++i ) { if ( 0 == validCipherSpec( &(priv->sa[i].spec), now ) ) { time_t remaining = priv->sa[i].spec.valid_until - now; traceEvent( TRACE_INFO, "transop_tf choosing tx_sa=%u (valid for %lu sec)", priv->sa[i].sa_id, remaining ); priv->tx_sa=i; found=1; break; } else traceEvent( TRACE_DEBUG, "transop_tf tick rejecting sa=%u %lu -> %lu", priv->sa[i].sa_id, priv->sa[i].spec.valid_from, priv->sa[i].spec.valid_until ); } if ( 0==found) traceEvent( TRACE_INFO, "transop_tf no keys are currently valid. Keeping tx_sa=%u", priv->tx_sa ); else { r.can_tx = 1; r.tx_spec.t = NTVL_TRANSFORM_ID_TWOFISH; r.tx_spec = priv->sa[priv->tx_sa].spec; } return r; }
void dumpCacheStats(u_int timeDifference) { #ifdef HAVE_REDIS int id; u_int32_t totNumGets = 0, totNumSets = 0; float s, g; for(id=0; id<MAX_NUM_REDIS_CONNECTIONS; id++) { u_int32_t numGets = readWriteGlobals->redis.numGetCommands[id]-readWriteGlobals->redis.numLastGetCommands[id]; u_int32_t numSets = readWriteGlobals->redis.numSetCommands[id]-readWriteGlobals->redis.numLastSetCommands[id]; #ifdef FULL_STATS g = (timeDifference > 0) ? ((float)numGets)/(float)timeDifference : 0; s = (timeDifference > 0) ? ((float)numSets)/(float)timeDifference : 0; if(readWriteGlobals->redis.queuedSetDeleteCommands[id] || numGets || numSets) traceEvent(TRACE_NORMAL, "Redis Cache [%d][write queue: actual %u/max %u][%u total/%.1f get/sec][%u total/%.1f set/sec]", id, readWriteGlobals->redis.queuedSetDeleteCommands[id], readWriteGlobals->redis.maxQueuedSetDeleteCommands[id], numGets, g, numSets, s); #endif readWriteGlobals->redis.numLastGetCommands[id] = readWriteGlobals->redis.numGetCommands[id]; readWriteGlobals->redis.numLastSetCommands[id] = readWriteGlobals->redis.numSetCommands[id]; totNumGets += numGets, totNumSets += numSets; } g = (timeDifference > 0) ? ((float)totNumGets)/(float)timeDifference : 0; s = (timeDifference > 0) ? ((float)totNumSets)/(float)timeDifference : 0; traceEvent(TRACE_NORMAL, "Redis Cache [%u total/%.1f get/sec][%u total/%.1f set/sec]", (unsigned int)totNumGets, (float)g, (unsigned int)totNumSets, (float)s); #endif dumpLruCacheStats(timeDifference); }
int createLocalCacheServer() { #ifdef HAVE_REDIS int sockopt = 1, rc; struct sockaddr_in sockIn; struct addrinfo hints, *ai = NULL; if(readOnlyGlobals.redis.local_ucloud_port == 0) return(0); errno = 0; readOnlyGlobals.redis.local_server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if((readOnlyGlobals.redis.local_server_socket < 0) || (errno != 0)) { traceEvent(TRACE_ERROR, "Unable to create server socket [%s/%d]", strerror(errno), errno); exit(-1); } errno = 0; rc = setsockopt(readOnlyGlobals.redis.local_server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)); memset(&sockIn, 0, sizeof(sockIn)); sockIn.sin_family = AF_INET, sockIn.sin_port = (int)htons(readOnlyGlobals.redis.local_ucloud_port), errno = 0; rc = bind(readOnlyGlobals.redis.local_server_socket, (struct sockaddr *)&sockIn, sizeof(sockIn)); if((readOnlyGlobals.redis.local_server_socket < 0) || (errno != 0)) { traceEvent(TRACE_ERROR, "Unable to bind to the specified port [%s/%d]", strerror(errno), errno); exit(-1); } errno = 0; rc = listen(readOnlyGlobals.redis.local_server_socket, 1 /* 1 client max */); pthread_create(&readOnlyGlobals.redis.local_server_loop, NULL, redisLocalServerLoop, NULL); #endif return(0); }
/** Update the edge table with the details of the edge which contacted the * supernode. */ static int update_edge( n2n_sn_t * sss, const n2n_mac_t edgeMac, const n2n_community_t community, const n2n_sock_t * sender_sock, time_t now) { macstr_t mac_buf; n2n_sock_str_t sockbuf; struct peer_info * scan; traceEvent( TRACE_DEBUG, "update_edge for %s [%s]", macaddr_str( mac_buf, edgeMac ), sock_to_cstr( sockbuf, sender_sock ) ); scan = find_peer_by_mac( sss->edges, edgeMac ); if ( NULL == scan ) { /* Not known */ scan = (struct peer_info*)calloc(1, sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ memcpy(scan->community_name, community, sizeof(n2n_community_t) ); memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t)); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); /* insert this guy at the head of the edges list */ scan->next = sss->edges; /* first in list */ sss->edges = scan; /* head of list points to new scan */ traceEvent( TRACE_INFO, "update_edge created %s ==> %s", macaddr_str( mac_buf, edgeMac ), sock_to_cstr( sockbuf, sender_sock ) ); } else { /* Known */ if ( (0 != memcmp(community, scan->community_name, sizeof(n2n_community_t))) || (0 != sock_equal(sender_sock, &(scan->sock) )) ) { memcpy(scan->community_name, community, sizeof(n2n_community_t) ); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); traceEvent( TRACE_INFO, "update_edge updated %s ==> %s", macaddr_str( mac_buf, edgeMac ), sock_to_cstr( sockbuf, sender_sock ) ); } else { traceEvent( TRACE_DEBUG, "update_edge unchanged %s ==> %s", macaddr_str( mac_buf, edgeMac ), sock_to_cstr( sockbuf, sender_sock ) ); } } scan->last_seen = now; return 0; }
int transop_twofish_setup( ntvl_trans_op_t * ttt, ntvl_sa_t sa_num, uint8_t * encrypt_pwd, uint32_t encrypt_pwd_len ) { int retval = 1; transop_tf_t * priv = NULL; if ( ttt->priv ) transop_deinit_twofish( ttt ); memset( ttt, 0, sizeof( ntvl_trans_op_t ) ); priv = (transop_tf_t *) malloc( sizeof(transop_tf_t) ); if ( NULL != priv ) { size_t i; sa_twofish_t * sa=NULL; /* install the private structure. */ ttt->priv = priv; for(i=0; i<NTVL_TWOFISH_NUM_SA; ++i) { sa = &(priv->sa[i]); sa->sa_id=0; memset( &(sa->spec), 0, sizeof(ntvl_cipherspec_t) ); sa->enc_tf=NULL; sa->dec_tf=NULL; } priv->num_sa=1; /* There is one SA in the array. */ priv->tx_sa=0; sa = &(priv->sa[priv->tx_sa]); sa->sa_id=sa_num; sa->spec.valid_until = 0x7fffffff; /* This is a preshared key setup. Both Tx and Rx are using the same security association. */ sa->enc_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); sa->dec_tf = TwoFishInit(encrypt_pwd, encrypt_pwd_len); if ( (sa->enc_tf) && (sa->dec_tf) ) { ttt->transform_id = NTVL_TRANSFORM_ID_TWOFISH; ttt->deinit = transop_deinit_twofish; ttt->addspec = transop_addspec_twofish; ttt->tick = transop_tick_twofish; /* chooses a new tx_sa */ ttt->fwd = transop_encode_twofish; ttt->rev = transop_decode_twofish; retval = 0; } else traceEvent( TRACE_ERROR, "TwoFishInit failed" ); } else { memset( ttt, 0, sizeof(ntvl_trans_op_t) ); traceEvent( TRACE_ERROR, "Failed to allocate priv for twofish" ); } return retval; }
void buildActivePluginsList(V9V10TemplateElementId *template_element_list[]) { int plugin_idx = 0; num_active_plugins = 0; while(all_plugins[plugin_idx] != NULL) { u_int8_t is_http = 0, is_dns = 0, is_mysql = 0; traceEvent(TRACE_INFO, "Scanning plugin %s", all_plugins[plugin_idx]->name); if(strcasestr(all_plugins[plugin_idx]->name, "http")) { is_http = 1; if(readOnlyGlobals.enableHttpPlugin) all_plugins[plugin_idx]->always_enabled = 1; } if(strcasestr(all_plugins[plugin_idx]->name, "dns")) { is_dns = 1; if(readOnlyGlobals.enableDnsPlugin) all_plugins[plugin_idx]->always_enabled = 1; } if(strcasestr(all_plugins[plugin_idx]->name, "mysql")) { is_mysql = 1; if(readOnlyGlobals.enableMySQLPlugin) all_plugins[plugin_idx]->always_enabled = 1; } if(all_plugins[plugin_idx]->always_enabled) { all_active_plugins[num_active_plugins++] = all_plugins[plugin_idx]; } else if(all_plugins[plugin_idx]->getPluginTemplateFctn != NULL) { int j; j = 0; while(template_element_list[j] != NULL) { if(all_plugins[plugin_idx]->getPluginTemplateFctn(template_element_list[j]->templateElementName)) { all_active_plugins[num_active_plugins++] = all_plugins[plugin_idx]; if(is_dns) readOnlyGlobals.enableDnsPlugin = 1; else if(is_http) readOnlyGlobals.enableHttpPlugin = 1; else if(is_mysql) readOnlyGlobals.enableMySQLPlugin = 1; traceEvent(TRACE_INFO, "Enabling plugin %s", all_plugins[plugin_idx]->name); break; } j++; } } plugin_idx++; } all_active_plugins[num_active_plugins] = NULL; traceEvent(TRACE_NORMAL, "%d plugin(s) enabled", num_active_plugins); }
/* Parse the preference file */ void parse_preference_file(char *path /* path of the preference file */) { FILE *fd = fopen(path, "r"); char buf[256]; int line = 1; if(!fd) { traceEvent(TRACE_WARNING, "Unable to open preference file %s: ignored.", path); return; } /* # Source IP Collector IP:port 192.168.10.253 192.168.100.200:2055 192.168.20.253 192.168.100.100:2055 */ while(fgets(buf, sizeof(buf), fd)) { char *source = NULL, *collector = NULL, *backup = NULL, *tok_state; if((buf[0] == '#') || (buf[0] == '\0') || (buf[0] == '\n') || (buf[0] == '\r')) continue; else buf[strlen(buf)-1] = '\0'; if((source = strtok_r(buf, "\t ", &tok_state)) != NULL) collector = strtok_r(NULL, "\t ", &tok_state); if(source && collector) { int collector_id = do_add_collector(collector); struct in_addr addr; int idx = -1, i; nf_probes[num_nf_probes].source_addr.s_addr = inet_addr(source); for(i=0; i<num_nf_probes; i++) if(nf_probes[i].source_addr.s_addr == nf_probes[num_nf_probes].source_addr.s_addr) { idx = i; break; } if(idx != -1) { traceEvent(TRACE_WARNING, "Probe %s defined multiple times: ignored duplicates", source); } else { nf_probes[num_nf_probes].nf_collector_id = collector_id; num_nf_probes++; traceEvent(TRACE_NORMAL, "Probe %s defined [total: %d]", source, num_nf_probes); } } else traceEvent(TRACE_WARNING, "Wrong format for line %s:%d", path, line); line++; } fclose(fd); }
int connectToRemoteCache(void) { #ifdef HAVE_REDIS struct timeval timeout = { 1, 500000 }; // 1.5 seconds int num, i; if(unlikely(readOnlyGlobals.enable_debug)) traceEvent(TRACE_NORMAL, "[Redis] %s(%s:%u)", __FUNCTION__, readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port); /* Synchronous */ #ifndef WIN32 if(readOnlyGlobals.redis.remote_redis_host[0] == '/') readOnlyGlobals.redis.read_context = redisConnectUnix(readOnlyGlobals.redis.remote_redis_host); else #endif readOnlyGlobals.redis.read_context = redisConnectWithTimeout(readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port, timeout); if(readOnlyGlobals.redis.read_context->err) { traceEvent(TRACE_ERROR, "Redis Connection error: %s", readOnlyGlobals.redis.read_context->errstr); exit(-1); } /* Asynchronous */ for(i=0; i<MAX_NUM_REDIS_CONNECTIONS; i++) { #ifndef WIN32 if(readOnlyGlobals.redis.remote_redis_host[0] == '/') readOnlyGlobals.redis.write_context[i] = redisConnectUnix(readOnlyGlobals.redis.remote_redis_host); else #endif readOnlyGlobals.redis.write_context[i] = redisConnectWithTimeout(readOnlyGlobals.redis.remote_redis_host, readOnlyGlobals.redis.remote_redis_port, timeout); if(readOnlyGlobals.redis.write_context[i]->err) { traceEvent(TRACE_ERROR, "Redis Connection error: %s", readOnlyGlobals.redis.write_context[i]->errstr); exit(-1); } } pthread_rwlock_init(&readOnlyGlobals.redis.lock_get, NULL); for(i=0; i<MAX_NUM_REDIS_CONNECTIONS; i++) { unsigned long id = i; pthread_rwlock_init(&readOnlyGlobals.redis.lock_set_delete[i], NULL); pthread_create(&readOnlyGlobals.redis.reply_loop, NULL, redisAsyncLoop, (void*)id); } createLocalCacheServer(); #endif return(0); }
void log_SNM_REQ( const n2n_SNM_REQ_t *req ) { int i; traceEvent( TRACE_DEBUG, "REQ Communities=%d", req->comm_num ); if (req->comm_ptr) { for(i = 0; i < req->comm_num; i++) { traceEvent( TRACE_DEBUG, "\t[%d] len=%d name=%s", i, req->comm_ptr[i].size, req->comm_ptr[i].name ); } } }
static int transop_addspec_twofish( n2n_trans_op_t * arg, const n2n_cipherspec_t * cspec ) { int retval = 1; ssize_t pstat=-1; transop_tf_t * priv = (transop_tf_t *)arg->priv; uint8_t keybuf[N2N_MAX_KEYSIZE]; if ( priv->num_sa < N2N_TWOFISH_NUM_SA ) { const char * op = (const char *)cspec->opaque; const char * sep = index( op, '_' ); if ( sep ) { char tmp[256]; size_t s; s = sep - op; memcpy( tmp, cspec->opaque, s ); tmp[s]=0; s = strlen(sep+1); /* sep is the _ which might be immediately followed by NULL */ priv->sa[priv->num_sa].spec = *cspec; priv->sa[priv->num_sa].sa_id = strtoul(tmp, NULL, 10); pstat = n2n_parse_hex( keybuf, N2N_MAX_KEYSIZE, sep+1, s ); if ( pstat > 0 ) { priv->sa[priv->num_sa].enc_tf = TwoFishInit( keybuf, pstat); priv->sa[priv->num_sa].dec_tf = TwoFishInit( keybuf, pstat); traceEvent( TRACE_DEBUG, "transop_addspec_twofish sa_id=%u data=%s.\n", priv->sa[priv->num_sa].sa_id, sep+1); ++(priv->num_sa); retval = 0; } } else { traceEvent( TRACE_ERROR, "transop_addspec_twofish : bad key data - missing '_'.\n"); } } else { traceEvent( TRACE_ERROR, "transop_addspec_twofish : full.\n"); } return retval; }
static int load_snm_info(n2n_sn_t *sss) { int new_ones = 0; struct sn_info *p = NULL; /* load supernodes */ struct sn_info *cmd_line_list = sss->supernodes.list_head; sss->supernodes.list_head = NULL; sprintf(sss->supernodes.filename, "SN_SNM_%d", sss->sn_port); if (read_sn_list_from_file( sss->supernodes.filename, &sss->supernodes.list_head)) { traceEvent(TRACE_ERROR, "Failed to open supernodes file. %s", strerror(errno)); return -1; } /* check if we had some new supernodes before reading from file */ p = cmd_line_list; while (p) { new_ones += update_supernodes(&sss->supernodes, &p->sn); p = p->next; } clear_sn_list(&cmd_line_list); if (new_ones) { write_sn_list_to_file(sss->supernodes.filename, sss->supernodes.list_head); } /* load communities */ sprintf(sss->communities.filename, "SN_COMM_%d", sss->sn_port); if (read_comm_list_from_file( sss->communities.filename, &sss->communities.persist)) { traceEvent(TRACE_ERROR, "Failed to open communities file. %s", strerror(errno)); return -1; } if (sn_list_size(sss->supernodes.list_head) == 0) /* first running supernode */ { sss->snm_discovery_state = N2N_SNM_STATE_READY; } return 0; }
char* _formatTime(time_t *theTime, char* outStr, int outStrLen, char* file, int line) { struct tm *locTime; struct tm myLocTime; if((locTime = localtime_r(theTime, &myLocTime)) == NULL) { traceEvent(CONST_TRACE_WARNING, "localtime_r failed: [%d/%s]", errno, strerror(errno)); outStr[0] = '\0'; } else { if(strftime(outStr, outStrLen, CONST_LOCALE_TIMESPEC, locTime) == 0) traceEvent(CONST_TRACE_ERROR, "Buffer too short @ %s:%d for formatTime() [%s]", file, line, outStr); } return(outStr); }
static int transop_decode_null( ntvl_trans_op_t * arg, uint8_t * outbuf, size_t out_len, const uint8_t * inbuf, size_t in_len ) { int retval = -1; traceEvent( TRACE_DEBUG, "decode_null %lu", in_len ); if ( out_len >= in_len ) { memcpy( outbuf, inbuf, in_len ); retval = in_len; } else traceEvent( TRACE_DEBUG, "decode_null %lu too big for packet buffer", in_len ); return retval; }
void termPlugins() { int i; traceEvent(TRACE_INFO, "Terminating plugins."); i = 0; while((i < MAX_NUM_PLUGINS) && (all_plugins[i] != NULL)) { if(all_plugins[i]->enabled && all_plugins[i]->termFctn) { traceEvent(TRACE_INFO, "Terminating %s", all_plugins[i]->name); all_plugins[i]->termFctn(); } i++; } }
/** @brief Open and configure the TAP device for packet read/write. * * This routine creates the interface via the tuntap driver then uses ifconfig * to configure address/mask and MTU. * * @param device - [inout] a device info holder object * @param dev - user-defined name for the new iface, * if NULL system will assign a name * @param device_ip - address of iface * @param device_mask - netmask for device_ip * @param mtu - MTU for device_ip * * @return - negative value on error * - non-negative file-descriptor on success */ int tuntap_open(tuntap_dev *device, char *dev, /* user-definable interface name, eg. edge0 */ char *device_ip, char *device_mask, const char * device_mac, int mtu) { char *tuntap_device = "/dev/net/tun"; #define N2N_LINUX_SYSTEMCMD_SIZE 128 char buf[N2N_LINUX_SYSTEMCMD_SIZE]; struct ifreq ifr; int rc; device->fd = open(tuntap_device, O_RDWR); if(device->fd < 0) { printf("ERROR: ioctl() [%s][%d]\n", strerror(errno), errno); return -1; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP|IFF_NO_PI; /* Want a TAP device for layer 2 frames. */ strncpy(ifr.ifr_name, dev, IFNAMSIZ); rc = ioctl(device->fd, TUNSETIFF, (void *)&ifr); if(rc < 0) { traceEvent(TRACE_ERROR, "ioctl() [%s][%d]\n", strerror(errno), rc); close(device->fd); return -1; } if ( device_mac ) { /* Set the hw address before bringing the if up. */ snprintf(buf, sizeof(buf), "/sbin/ifconfig %s hw ether %s", ifr.ifr_name, device_mac ); system(buf); traceEvent(TRACE_INFO, "Setting MAC: %s", buf); } snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s netmask %s mtu %d up", ifr.ifr_name, device_ip, device_mask, mtu); system(buf); traceEvent(TRACE_INFO, "Bringing up: %s", buf); device->ip_addr = inet_addr(device_ip); device->device_mask = inet_addr(device_mask); read_mac(dev, (char*)device->mac_addr); return(device->fd); }
/* Add a new collector Return the collector id, or -1 if not found */ int do_add_collector(char* host_and_port /* Format host:port */) { struct hostent *h; char *host = NULL, *port = NULL; int idx, rc; struct in_addr addr; host = strtok(host_and_port, ":"); if(host) port = strtok(NULL, ":"); if((!host) || (!port)) { traceEvent(TRACE_ERROR, "Invalid host:port format. Skipped."); return(-1); } h = gethostbyname(host); if(h == NULL) { traceEvent(TRACE_ERROR, "Unknown host '%s'", host); return(-1); } else memcpy((char*)&addr, h->h_addr_list[0], sizeof(addr)); if(num_nf_collectors >= MAX_NUM_COLLECTORS) { traceEvent(TRACE_ERROR, "Too many nf_collectors defined (%d)", num_nf_collectors); return(-1); } if((rc = do_find_collector(addr, atoi(port))) != -1) { traceEvent(TRACE_INFO, "Collector %s:%s has been defined multiple times: duplicates are discarded", host, port); return(rc); } idx = num_nf_collectors; memset(&nf_collectors[idx], 0, sizeof(nf_collectors[idx])); nf_collectors[idx].addr.sin_family = h->h_addrtype; memcpy((char *)&nf_collectors[idx].addr.sin_addr.s_addr, &addr, sizeof(addr)); nf_collectors[idx].addr.sin_port = htons(atoi(port)); #ifndef linux nf_collectors[idx].addr.sin_len = sizeof(struct sockaddr_in); #endif num_nf_collectors++; traceEvent(TRACE_NORMAL, "Added new collector %s:%d [total: %d]", host, atoi(port), num_nf_collectors); return(idx); }
/** The twofish packet format consists of: * * - a 8-bit twofish encoding version in clear text * - a 32-bit SA number in clear text * - ciphertext encrypted from a 32-bit nonce followed by the payload. * * [V|SSSS|nnnnDDDDDDDDDDDDDDDDDDDDD] * |<------ encrypted ------>| */ static int transop_encode_twofish( ntvl_trans_op_t * arg, uint8_t * outbuf, size_t out_len, const uint8_t * inbuf, size_t in_len ) { int len=-1; transop_tf_t * priv = (transop_tf_t *)arg->priv; uint8_t assembly[NTVL_PKT_BUF_SIZE]; uint32_t * pnonce; if ( (in_len + TRANSOP_TF_NONCE_SIZE) <= NTVL_PKT_BUF_SIZE ) { if ( (in_len + TRANSOP_TF_NONCE_SIZE + TRANSOP_TF_SA_SIZE + TRANSOP_TF_VER_SIZE) <= out_len ) { size_t idx=0; sa_twofish_t * sa; size_t tx_sa_num = 0; /* The transmit sa is periodically updated */ tx_sa_num = tf_choose_tx_sa( priv ); sa = &(priv->sa[tx_sa_num]); /* Proper Tx SA index */ traceEvent( TRACE_DEBUG, "encode_twofish %lu with SA %lu.", in_len, sa->sa_id ); /* Encode the twofish format version. */ encode_uint8( outbuf, &idx, NTVL_TWOFISH_TRANSFORM_VERSION ); /* Encode the security association (SA) number */ encode_uint32( outbuf, &idx, sa->sa_id ); /* The assembly buffer is a source for encrypting data. The nonce is * written in first followed by the packet payload. The whole * contents of assembly are encrypted. */ pnonce = (uint32_t *)assembly; *pnonce = rand(); memcpy( assembly + TRANSOP_TF_NONCE_SIZE, inbuf, in_len ); /* Encrypt the assembly contents and write the ciphertext after the SA. */ len = TwoFishEncryptRaw( assembly, /* source */ outbuf + TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE, in_len + TRANSOP_TF_NONCE_SIZE, /* enc size */ sa->enc_tf); if ( len > 0 ) len += TRANSOP_TF_VER_SIZE + TRANSOP_TF_SA_SIZE; /* size of data carried in UDP. */ else traceEvent( TRACE_ERROR, "encode_twofish encryption failed." ); } else traceEvent( TRACE_ERROR, "encode_twofish outbuf too small." ); } else traceEvent( TRACE_ERROR, "encode_twofish inbuf too big to encrypt." ); return len; }
void free_lru_cache(struct LruCache *cache) { int i; if(unlikely(traceLRU)) traceEvent(TRACE_NORMAL, "%s()", __FUNCTION__); for(i=0; i<cache->hash_size; i++) { struct LruCacheEntry *head = cache->hash[i]; while(head != NULL) { struct LruCacheEntry *next = head->next; free_lru_cache_entry(cache, head); free(head); #ifdef FULL_STATS cache->mem_size -= sizeof(struct LruCacheEntry); #endif head = next; } } free(cache->hash); #ifdef FULL_STATS cache->mem_size -= cache->hash_size*sizeof(struct LruCacheEntry*); #endif free(cache->current_hash_size); #ifdef FULL_STATS cache->mem_size -= cache->hash_size*sizeof(u_int32_t); #endif pthread_rwlock_destroy(&cache->lruLock); }
char* formatThroughput(float numBytes /* <=== Bytes/second */, u_char htmlFormat, char* outStr, int outStrLen) { float numBits; int divider = 1000; /* As SNMP does instead of using 1024 ntop divides for 1000 */ char *separator; if(htmlFormat) separator = myGlobals.separator; else separator = " "; if(numBytes < 0) numBytes = 0; /* Sanity check */ numBits = numBytes*8; if (numBits < divider) { safe_snprintf(__FILE__, __LINE__, outStr, outStrLen, "%.1f%sbit/s", numBits, separator); } else if (numBits < (divider*divider)) { safe_snprintf(__FILE__, __LINE__, outStr, outStrLen, "%.1f%sKbit/s", ((float)(numBits)/divider), separator); } else { safe_snprintf(__FILE__, __LINE__, outStr, outStrLen, "%.1f%sMbit/s", ((float)(numBits)/1048576), separator); } #ifdef DEBUG traceEvent(CONST_TRACE_INFO, "%.2f = %s", numBytes, outStr); #endif return(outStr); }
/* Fill out the ip_addr value from the interface. Called to pick up dynamic * address changes. */ void tuntap_get_address(struct tuntap_dev *tuntap) { FILE * fp=NULL; ssize_t nread=0; char buf[N2N_LINUX_SYSTEMCMD_SIZE]; /* Would rather have a more direct way to get the inet address but a netlink * socket is overkill and probably less portable than ifconfig and sed. */ /* If the interface has no address (0.0.0.0) there will be no inet addr * line and the returned string will be empty. */ snprintf( buf, sizeof(buf), "/sbin/ifconfig %s | /bin/sed -e '/inet addr:/!d' -e 's/^.*inet addr://' -e 's/ .*$//'", tuntap->dev_name ); fp=popen(buf, "r"); if (fp ) { memset(buf,0,N2N_LINUX_SYSTEMCMD_SIZE); /* make sure buf is NULL terminated. */ nread=fread(buf, 1, 15, fp); fclose(fp); fp=NULL; traceEvent(TRACE_INFO, "ifconfig address = %s", buf); tuntap->ip_addr = inet_addr(buf); } }