Beispiel #1
0
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);
}
Beispiel #2
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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 : "" );
        }
    }
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
/* 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);
}
Beispiel #8
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__);
  }
}
Beispiel #9
0
/*
  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);
  }
}
Beispiel #10
0
/** 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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
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;
}
Beispiel #15
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;
}
Beispiel #16
0
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);
}
Beispiel #17
0
/* 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);
}
Beispiel #18
0
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);
}
Beispiel #19
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 );
        }
    }
}
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
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);
}
Beispiel #23
0
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;
}
Beispiel #24
0
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++;
  }
}
Beispiel #25
0
/** @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);
}
Beispiel #26
0
/*
  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);
}
Beispiel #27
0
/** 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;
}
Beispiel #28
0
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);
}
Beispiel #29
0
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);
}
Beispiel #30
0
/* 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);
    }
}