File: server_helper.cc

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (140 lines) | stat: -rw-r--r-- 4,948 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "log/strict_consistent_store.h"
#include "server/server.h"
#include "server/server_helper.h"
#include "util/fake_etcd.h"

using cert_trans::Server;
using google::RegisterFlagValidator;
using std::string;
using std::unique_ptr;

// Main server configuration flags
DEFINE_string(server, "localhost", "Server host");
DEFINE_int32(port, 9999, "Server port");
DEFINE_string(etcd_root, "/root", "Root of cluster entries in etcd.");
DEFINE_string(etcd_servers, "",
              "Comma separated list of 'hostname:port' of the etcd server(s)");
DEFINE_bool(i_know_stand_alone_mode_can_lose_data, false,
            "Set this to allow stand-alone mode, even though it will lose "
            "submissions in the case of a crash.");

// Storage related flags
// TODO(alcutter): Just specify a root dir with a single flag.
DEFINE_string(cert_dir, "", "Storage directory for certificates");
DEFINE_string(tree_dir, "", "Storage directory for trees");
DEFINE_string(meta_dir, "", "Storage directory for meta info");
DEFINE_string(sqlite_db, "",
              "SQLite database for certificate and tree storage");
DEFINE_string(leveldb_db, "",
              "LevelDB database for certificate and tree storage");
// TODO(ekasper): sanity-check these against the directory structure.
DEFINE_int32(cert_storage_depth, 0,
             "Subdirectory depth for certificates; if the directory is not "
             "empty, must match the existing depth.");
DEFINE_int32(tree_storage_depth, 0,
             "Subdirectory depth for tree signatures; if the directory is not "
             "empty, must match the existing depth");

// Basic sanity checks on flag values.
static bool ValidateWrite(const char* flagname, const string& path) {
  if (path != "" && access(path.c_str(), W_OK) != 0) {
    std::cout << "Cannot modify " << flagname << " at " << path << std::endl;
    return false;
  }
  return true;
}

static bool ValidateIsNonNegative(const char* flagname, int value) {
  if (value < 0) {
    std::cout << flagname << " must not be negative" << std::endl;
    return false;
  }
  return true;
}

static bool ValidatePort(const char*, int port) {
  if (port <= 0 || port > 65535) {
    std::cout << "Port value " << port << " is invalid. " << std::endl;
    return false;
  }
  return true;
}

static const bool port_dummy =
    RegisterFlagValidator(&FLAGS_port, &ValidatePort);

static const bool cert_dir_dummy =
    RegisterFlagValidator(&FLAGS_cert_dir, &ValidateWrite);

static const bool tree_dir_dummy =
    RegisterFlagValidator(&FLAGS_tree_dir, &ValidateWrite);

static const bool c_st_dummy =
    RegisterFlagValidator(&FLAGS_cert_storage_depth, &ValidateIsNonNegative);

static const bool t_st_dummy =
    RegisterFlagValidator(&FLAGS_tree_storage_depth, &ValidateIsNonNegative);

namespace cert_trans {

void EnsureValidatorsRegistered() {
  CHECK(cert_dir_dummy && tree_dir_dummy && c_st_dummy && t_st_dummy &&
        port_dummy);
}


bool IsStandalone(bool warn_data_loss) {
  const bool stand_alone_mode(FLAGS_etcd_servers.empty());
  if (stand_alone_mode && warn_data_loss &&
      !FLAGS_i_know_stand_alone_mode_can_lose_data) {
    LOG(FATAL) << "attempted to run in stand-alone mode without the "
                  "--i_know_stand_alone_mode_can_lose_data flag";
  }

  if (!stand_alone_mode && FLAGS_server.empty()) {
    // Part of a cluster so server must be set
    LOG(FATAL) << "not in stand-alone mode but --server is empty";
  }

  return stand_alone_mode;
}


unique_ptr<Database> ProvideDatabase() {
  if (!FLAGS_sqlite_db.empty() + !FLAGS_leveldb_db.empty() +
          (!FLAGS_cert_dir.empty() | !FLAGS_tree_dir.empty()) !=
      1) {
    LOG(FATAL) << "Must specify exactly one database type. Check flags.";
  }

  if (FLAGS_sqlite_db.empty() && FLAGS_leveldb_db.empty()) {
    CHECK_NE(FLAGS_cert_dir, FLAGS_tree_dir)
        << "Certificate directory and tree directory must differ";
  }

  if (!FLAGS_sqlite_db.empty()) {
    return unique_ptr<Database>(new SQLiteDB(FLAGS_sqlite_db));
  } else if (!FLAGS_leveldb_db.empty()) {
    return unique_ptr<Database>(new LevelDB(FLAGS_leveldb_db));
  } else {
    return unique_ptr<Database>(
        new FileDB(new FileStorage(FLAGS_cert_dir, FLAGS_cert_storage_depth),
                   new FileStorage(FLAGS_tree_dir, FLAGS_tree_storage_depth),
                   new FileStorage(FLAGS_meta_dir, 0)));
  }

  LOG(FATAL) << "No usable database is configured by flags";
}


unique_ptr<EtcdClient> ProvideEtcdClient(libevent::Base* event_base,
                                         ThreadPool* pool,
                                         UrlFetcher* fetcher) {
  // No need to enforce --warn-data-loss here as it will already have been
  // done if required
  return unique_ptr<EtcdClient>(
      IsStandalone(false)
          ? new FakeEtcdClient(event_base)
          : new EtcdClient(pool, fetcher, SplitHosts(FLAGS_etcd_servers)));
}
}  // namespace cert_trans