<commit_before>//
// Created by mabaiming on 16-8-29.
//
#include "tcp_client.h"

#include "common.h"
#include "logger.h"
#include "tunnel_package.h"

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/socket.h>

using namespace std;
using namespace Common;

void
TcpClient::init(const string& addrStr, int tunnelRetryInterval,
    const string& trafficIp_, uint16_t trafficPort_,
    const string& tunnelSecret, int tunnelHeartbeat) {
  if (addrStr.empty()) {
    log_error << "tunnel addr list is empty!";
    exit(EXIT_FAILURE);
  }
  addrListStr = addrStr;
  if (!refreshAddrList()) {
    exit(EXIT_FAILURE);
  }
  secret = tunnelSecret;
  if (tunnelHeartbeat <= 0) {
    log_error << "invalid heartbeat, use default " << heartbeat;
  } else {
    heartbeat = tunnelHeartbeat;
  }
  trafficServerIp = trafficIp_;
  trafficServerPort = trafficPort_;
  tunnelServerFd = -1;
  retryInterval = tunnelRetryInterval;
  retryConnectTunnelServer();
}

bool
TcpClient::refreshAddrList() {
  if (!parseAddressList(tunnelServerList, addrListStr)) {
    log_error << "invalid addrList: " << addrListStr;
    return false;
  }
  for (int i = 0; i < tunnelServerList.size(); ++i) {
    log_info << "tunnelServer[" << i << "]: "
        << tunnelServerList[i].toString() << endl;
  }
  return true;
}

void
TcpClient::retryConnectTunnelServer() {
  static bool firstConnect = true;
  srand(time(0));
  int retryTime = 0;
  while (tunnelServerFd < 0) {
    ++retryTime;
    if (retryTime > 10) {
      refreshAddrList();
      retryTime = 0;
    }
    int index = rand() % tunnelServerList.size();
    Addr& addr = tunnelServerList[index];
    if (!firstConnect) {
      sleep(retryInterval);
    }
    firstConnect = false;
    int fd = connectServer(addr.ip, addr.port);
    if (fd > 0) {
      log_info << "use tunnel server addr(" << index << "/"
          << tunnelServerList.size() << "): " << addr.ip << ":" << addr.port;
      tunnelServerFd = fd;
      return;
    }
    if (retryInterval > 0) {
      log_error << "retry " << addr.ip << ":" << addr.port
          << " after " << retryInterval << " seconds";
      sleep(retryInterval);
    } else {
      exit(EXIT_FAILURE);
    }
  }
}

void
TcpClient::cleanUpTrafficClient(int fakeFd) {
  log_debug << "clean up trafficClient, fakeFd: " << fakeFd;
  map<int, int>::iterator it = trafficClientMap.find(fakeFd);
  if (it != trafficClientMap.end()) {
    sendTunnelState(tunnelServerFd, fakeFd, TunnelPackage::STATE_CLOSE);
    cleanUpFd(it->second);
    trafficClientMap.erase(fakeFd);
    trafficServerMap.erase(it->second);
  }
}

void
TcpClient::cleanUpTrafficServer(int fd) {
  map<int, int>::iterator it = trafficServerMap.find(fd);
  if (it != trafficServerMap.end()) {
    log_debug << "clean up trafficServer: " << addrRemote(fd);
    cleanUpFd(fd);
    trafficServerMap.erase(fd);
    trafficClientMap.erase(it->second);
  }
}

void
TcpClient::resetTunnelServer() {
  map<int, int>::iterator it = trafficServerMap.begin();
  for (; it != trafficServerMap.end(); ++it) {
    cleanUpFd(it->first);
  }
  trafficServerMap.clear();
  trafficClientMap.clear();
  cleanUpFd(tunnelServerFd);
  tunnelServerFd = -1;
  tunnelBuffer.clear();
  retryConnectTunnelServer();
}

bool
TcpClient::handleTunnelClient(uint32_t events, int eventFd) {
  log_error << "events: " << events << ", fd: " << eventFd;
  if (eventFd != tunnelServerFd) { // traffic from tunnel
    return false;
  }<commit_msg>remove used log code<commit_after>//
// Created by mabaiming on 16-8-29.
//
#include "tcp_client.h"

#include "common.h"
#include "logger.h"
#include "tunnel_package.h"

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/socket.h>

using namespace std;
using namespace Common;

void
TcpClient::init(const string& addrStr, int tunnelRetryInterval,
    const string& trafficIp_, uint16_t trafficPort_,
    const string& tunnelSecret, int tunnelHeartbeat) {
  if (addrStr.empty()) {
    log_error << "tunnel addr list is empty!";
    exit(EXIT_FAILURE);
  }
  addrListStr = addrStr;
  if (!refreshAddrList()) {
    exit(EXIT_FAILURE);
  }
  secret = tunnelSecret;
  if (tunnelHeartbeat <= 0) {
    log_error << "invalid heartbeat, use default " << heartbeat;
  } else {
    heartbeat = tunnelHeartbeat;
  }
  trafficServerIp = trafficIp_;
  trafficServerPort = trafficPort_;
  tunnelServerFd = -1;
  retryInterval = tunnelRetryInterval;
  retryConnectTunnelServer();
}

bool
TcpClient::refreshAddrList() {
  if (!parseAddressList(tunnelServerList, addrListStr)) {
    log_error << "invalid addrList: " << addrListStr;
    return false;
  }
  for (int i = 0; i < tunnelServerList.size(); ++i) {
    log_info << "tunnelServer[" << i << "]: "
        << tunnelServerList[i].toString() << endl;
  }
  return true;
}

void
TcpClient::retryConnectTunnelServer() {
  static bool firstConnect = true;
  srand(time(0));
  int retryTime = 0;
  while (tunnelServerFd < 0) {
    ++retryTime;
    if (retryTime > 10) {
      refreshAddrList();
      retryTime = 0;
    }
    int index = rand() % tunnelServerList.size();
    Addr& addr = tunnelServerList[index];
    if (!firstConnect) {
      sleep(retryInterval);
    }
    firstConnect = false;
    int fd = connectServer(addr.ip, addr.port);
    if (fd > 0) {
      log_info << "use tunnel server addr(" << index << "/"
          << tunnelServerList.size() << "): " << addr.ip << ":" << addr.port;
      tunnelServerFd = fd;
      return;
    }
    if (retryInterval > 0) {
      log_error << "retry " << addr.ip << ":" << addr.port
          << " after " << retryInterval << " seconds";
      sleep(retryInterval);
    } else {
      exit(EXIT_FAILURE);
    }
  }
}

void
TcpClient::cleanUpTrafficClient(int fakeFd) {
  log_debug << "clean up trafficClient, fakeFd: " << fakeFd;
  map<int, int>::iterator it = trafficClientMap.find(fakeFd);
  if (it != trafficClientMap.end()) {
    sendTunnelState(tunnelServerFd, fakeFd, TunnelPackage::STATE_CLOSE);
    cleanUpFd(it->second);
    trafficClientMap.erase(fakeFd);
    trafficServerMap.erase(it->second);
  }
}

void
TcpClient::cleanUpTrafficServer(int fd) {
  map<int, int>::iterator it = trafficServerMap.find(fd);
  if (it != trafficServerMap.end()) {
    log_debug << "clean up trafficServer: " << addrRemote(fd);
    cleanUpFd(fd);
    trafficServerMap.erase(fd);
    trafficClientMap.erase(it->second);
  }
}

void
TcpClient::resetTunnelServer() {
  map<int, int>::iterator it = trafficServerMap.begin();
  for (; it != trafficServerMap.end(); ++it) {
    cleanUpFd(it->first);
  }
  trafficServerMap.clear();
  trafficClientMap.clear();
  cleanUpFd(tunnelServerFd);
  tunnelServerFd = -1;
  tunnelBuffer.clear();
  retryConnectTunnelServer();
}

bool
TcpClient::handleTunnelClient(uint32_t events, int eventFd) {
  if (eventFd != tunnelServerFd) { // traffic from tunnel
    return false;
  }
{'fraction_non_alphanumeric': 0.1484047928396131, 'fraction_numerical': 0.006063230835859679, 'mean_word_length': 3.6747638326585697, 'pattern_counts': {'":': 4, '<': 149, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '68000', 'n_tokens_mistral': 2396, 'n_tokens_neox': 2420, 'n_words': 494}