"lenient-option-parsing": true
},
- // Command control socket configuration parameters for the Kea DHCPv6 server.
- "control-socket": {
- // Location of the UNIX domain socket file the DHCPv6 server uses
- // to receive control commands from the Kea Control Agent or the
- // local server administrator.
- "socket-name": "/tmp/kea6-ctrl-socket",
-
- // Control socket type used by the Kea DHCPv6 server. The 'unix'
- // socket is currently the only supported type.
- "socket-type": "unix"
- },
+ // Command control socket configuration parameters for the Kea DHCPv4 server.
+ "control-sockets": [
+ {
+ // Control socket type used by the Kea DHCPv4 server.
+ // Must be unix, http or https.
+ "socket-type": "unix",
+
+ // Location of the UNIX domain socket file the DHCPv4
+ // server uses to receive control commands from the
+ // local server administrator.
+ "socket-name": "/tmp/kea4-ctrl-socket"
+ },
+ {
+ // Control socket type used by the Kea DHCPv4 server.
+ // Must be unix, http or https.
+ "socket-type": "https",
+
+ // Address of the HTTPS socket the Kea DHCPv4 server should
+ // listen for incoming queries. In fact an alias of
+ // socket-name.
+ "socket-address": "::1",
+
+ // Port of the HTTPS socket the Kea DHCPv4 server
+ // should listen for incoming queries. If enabling HA
+ // and multi-threading, the 8000 port is used by the
+ // HA hook library http listener. When using HA hook
+ // library with multi-threading to function, make sure
+ // the port used by dedicated listener is different
+ // (e.g. 8001) than the one specified here. Note the
+ // commands should still be sent to a control socket.
+ // The dedicated listener is specifically for HA
+ // updates only.
+ "socket-port": 8000,
+
+ // TLS trust anchor (Certificate Authority). This is a
+ // file name or a directory path. Make sense with other
+ // TLS parameters only for the https control socket type.
+ "trust-anchor": "my-ca",
+
+ // TLS server certificate file name.
+ "cert-file": "my-cert",
+
+ // TLS server private key file name.
+ "key-file": "my-key",
+
+ // TLS require client certificates flag. Default is
+ // true and means require client certificates. False
+ // means they are optional.
+ "cert-required": true,
+
+ // Optional authentication.
+ "authentication": {
+
+ // Required authentication type. The only
+ // supported value is basic for the basic HTTP
+ // authentication.
+ "type": "basic",
+
+ // An optional parameter is the basic HTTP
+ // authentication realm. Its default is
+ // "kea-dhcpv4-server"
+ "realm": "kea-dhcpv4-server",
+
+ // This optional parameter can be used to specify a common
+ // prefix for files handling client credentials.
+ "directory": "/tmp/kea-creds",
+
+ // This list specifies the user ids and passwords
+ // to use for basic HTTP authentication. If empty
+ // or not present any client is authorized.
+ "clients": [
+ // This specifies an authorized client.
+ {
+ // The user id must not be empty or
+ // contain the ':' character. It is a
+ // mandatory parameter.
+ "user": "admin",
+
+ // If password is not specified an empty
+ // password is used.
+ "password": "1234"
+ },
+
+ // This specifies a hidden client.
+ {
+ // The user id is the content of the
+ // file /tmp/kea-creds/hiddenu.
+ "user-file": "hiddenu",
+
+ // The password is the content of the
+ // file /tmp/kea-creds/hiddenp.
+ "password-file": "hiddenp"
+ },
+
+ // This specifies a hidden client using a
+ // secret in a file.
+ {
+ // The secret is the content of the file
+ // /tmp/kea-creds/hiddens which must be in
+ // the <user-id>:<password> format.
+ "password-file": "hiddens"
+ }
+ ]
+ }
+ }
+ ],
+
// Specifies a prefix to be prepended to the generated Client FQDN.
// It may be specified at the global, shared-network, and subnet levels.
}
],
- // In control socket (more for the agent)
- "control-socket": {
- "socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket",
- "user-context": { "comment": "Indirect comment" }
- },
+ // In control sockets (more for the agent)
+ "control-sockets": [
+ {
+ "socket-type": "unix",
+ "socket-name": "/tmp/kea4-ctrl-socket",
+ "user-context": { "comment": "Indirect comment" }
+ },
+ {
+ "comment": "HTTP control socket",
+ "socket-type": "http",
+ "socket-address": "127.0.0.1",
+ "socket-port": 8000,
+
+ // In authentication
+ "authentication": {
+ "comment": "basic HTTP authentication",
+ "type": "basic",
+ // In basic HTTP authentication clients
+ "clients": [ {
+ "comment": "admin is authorized",
+ "user": "admin",
+ "password": "1234"
+ } ]
+ }
+ }
+ ],
// In shared networks
"shared-networks": [ {
control_socket: CONTROL_SOCKET {
ctx.unique("control-socket", ctx.loc2pos(@1));
+ ctx.unique("control-sockets", ctx.loc2pos(@1));
ElementPtr m(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("control-socket", m);
ctx.stack_.push_back(m);
control_sockets: CONTROL_SOCKETS {
ctx.unique("control-sockets", ctx.loc2pos(@1));
+ ctx.unique("control-socket", ctx.loc2pos(@1));
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("control-sockets", l);
ctx.stack_.push_back(l);
case isc::dhcp::Parser6Context::OPTION_DEF:
case isc::dhcp::Parser6Context::SERVER_ID:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
return isc::dhcp::Dhcp6Parser::make_TYPE(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("type", driver.loc_);
case isc::dhcp::Parser6Context::LEASE_DATABASE:
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::CLIENTS:
return isc::dhcp::Dhcp6Parser::make_USER(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("user", driver.loc_);
case isc::dhcp::Parser6Context::LEASE_DATABASE:
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::CLIENTS:
return isc::dhcp::Dhcp6Parser::make_PASSWORD(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("password", driver.loc_);
case isc::dhcp::Parser6Context::LEASE_DATABASE:
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
return isc::dhcp::Dhcp6Parser::make_TRUST_ANCHOR(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("trust-anchor", driver.loc_);
case isc::dhcp::Parser6Context::LEASE_DATABASE:
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
return isc::dhcp::Dhcp6Parser::make_CERT_FILE(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("cert-file", driver.loc_);
case isc::dhcp::Parser6Context::LEASE_DATABASE:
case isc::dhcp::Parser6Context::HOSTS_DATABASE:
case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
return isc::dhcp::Dhcp6Parser::make_KEY_FILE(driver.loc_);
default:
return isc::dhcp::Dhcp6Parser::make_STRING("key-file", driver.loc_);
case isc::dhcp::Parser6Context::CLIENT_CLASSES:
case isc::dhcp::Parser6Context::SERVER_ID:
case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
+ case isc::dhcp::Parser6Context::CLIENTS:
case isc::dhcp::Parser6Context::DHCP_QUEUE_CONTROL:
case isc::dhcp::Parser6Context::DHCP_MULTI_THREADING:
case isc::dhcp::Parser6Context::LOGGERS:
case isc::dhcp::Parser6Context::CLIENT_CLASSES:
case isc::dhcp::Parser6Context::SERVER_ID:
case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
+ case isc::dhcp::Parser6Context::CLIENTS:
case isc::dhcp::Parser6Context::DHCP_QUEUE_CONTROL:
case isc::dhcp::Parser6Context::DHCP_MULTI_THREADING:
case isc::dhcp::Parser6Context::LOGGERS:
}
}
+\"control-sockets\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::DHCP6:
+ return isc::dhcp::Dhcp6Parser::make_CONTROL_SOCKETS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("control-sockets", driver.loc_);
+ }
+}
+
\"socket-type\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::CONTROL_SOCKET:
}
}
+\"unix\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET_TYPE:
+ return isc::dhcp::Dhcp6Parser::make_UNIX(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("unix", driver.loc_);
+ }
+}
+
+\"http\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET_TYPE:
+ return isc::dhcp::Dhcp6Parser::make_HTTP(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("http", driver.loc_);
+ }
+}
+
+\"https\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET_TYPE:
+ return isc::dhcp::Dhcp6Parser::make_HTTPS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("https", driver.loc_);
+ }
+}
+
\"socket-name\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::CONTROL_SOCKET:
}
}
+\"socket-address\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_SOCKET_ADDRESS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("socket-address", driver.loc_);
+ }
+}
+
+\"socket-port\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_SOCKET_PORT(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("socket-port", driver.loc_);
+ }
+}
+
+\"authentication\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_AUTHENTICATION(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("authentication", driver.loc_);
+ }
+}
+
+\"basic\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::AUTH_TYPE:
+ return isc::dhcp::Dhcp6Parser::make_BASIC(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("basic", driver.loc_);
+ }
+}
+
+\"realm\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
+ return isc::dhcp::Dhcp6Parser::make_REALM(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("realm", driver.loc_);
+ }
+}
+
+\"directory\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
+ return isc::dhcp::Dhcp6Parser::make_DIRECTORY(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("directory", driver.loc_);
+ }
+}
+
+\"clients\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::AUTHENTICATION:
+ return isc::dhcp::Dhcp6Parser::make_CLIENTS(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("clients", driver.loc_);
+ }
+}
+
+\"user-file\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CLIENTS:
+ return isc::dhcp::Dhcp6Parser::make_USER_FILE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("user-file", driver.loc_);
+ }
+}
+
+\"password-file\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CLIENTS:
+ return isc::dhcp::Dhcp6Parser::make_PASSWORD_FILE(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("password-file", driver.loc_);
+ }
+}
+
+\"cert-required\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::CONTROL_SOCKET:
+ return isc::dhcp::Dhcp6Parser::make_CERT_REQUIRED(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("cert-required", driver.loc_);
+ }
+}
+
\"dhcp-queue-control\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
PACKET_QUEUE_SIZE "packet-queue-size"
CONTROL_SOCKET "control-socket"
+ CONTROL_SOCKETS "control-sockets"
SOCKET_TYPE "socket-type"
SOCKET_NAME "socket-name"
+ UNIX "unix"
+ HTTP "http"
+ HTTPS "https"
+ SOCKET_NAME "socket-name"
+ SOCKET_ADDRESS "socket-address"
+ SOCKET_PORT "socket-port"
+ AUTHENTICATION "authentication"
+ BASIC "basic"
+ REALM "realm"
+ DIRECTORY "directory"
+ CLIENTS "clients"
+ USER_FILE "user-file"
+ PASSWORD_FILE "password-file"
+ CERT_REQUIRED "cert-required"
DHCP_QUEUE_CONTROL "dhcp-queue-control"
ENABLE_QUEUE "enable-queue"
%type <ElementPtr> ncr_protocol_value
%type <ElementPtr> ddns_replace_client_name_value
%type <ElementPtr> ddns_conflict_resolution_mode_value
+%type <ElementPtr> control_socket_type_value
+%type <ElementPtr> auth_type_value
%printer { yyoutput << $$; } <*>;
| server_id
| dhcp4o6_port
| control_socket
+ | control_sockets
| dhcp_queue_control
| dhcp_ddns
| user_context
control_socket: CONTROL_SOCKET {
ctx.unique("control-socket", ctx.loc2pos(@1));
+ ctx.unique("control-sockets", ctx.loc2pos(@1));
ElementPtr m(new MapElement(ctx.loc2pos(@1)));
ctx.stack_.back()->set("control-socket", m);
ctx.stack_.push_back(m);
ctx.leave();
};
+control_sockets: CONTROL_SOCKETS {
+ ctx.unique("control-sockets", ctx.loc2pos(@1));
+ ctx.unique("control-socket", ctx.loc2pos(@1));
+ ElementPtr l(new ListElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("control-sockets", l);
+ ctx.stack_.push_back(l);
+ ctx.enter(ctx.CONTROL_SOCKET);
+} COLON LSQUARE_BRACKET control_socket_list RSQUARE_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+control_socket_list: %empty
+ | not_empty_control_socket_list
+ ;
+
+not_empty_control_socket_list: control_socket_entry
+ | not_empty_control_socket_list COMMA control_socket_entry
+ | not_empty_control_socket_list COMMA {
+ ctx.warnAboutExtraCommas(@2);
+ }
+ ;
+
+control_socket_entry: LCURLY_BRACKET {
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->add(m);
+ ctx.stack_.push_back(m);
+} control_socket_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
+
control_socket_params: control_socket_param
| control_socket_params COMMA control_socket_param
| control_socket_params COMMA {
}
;
-control_socket_param: socket_type
- | socket_name
+control_socket_param: control_socket_type
+ | control_socket_name
+ | control_socket_address
+ | control_socket_port
+ | authentication
+ | trust_anchor
+ | cert_file
+ | key_file
+ | cert_required
| user_context
| comment
| unknown_map_entry
;
-socket_type: SOCKET_TYPE {
+control_socket_type: SOCKET_TYPE {
ctx.unique("socket-type", ctx.loc2pos(@1));
- ctx.enter(ctx.NO_KEYWORD);
-} COLON STRING {
- ElementPtr stype(new StringElement($4, ctx.loc2pos(@4)));
- ctx.stack_.back()->set("socket-type", stype);
+ ctx.enter(ctx.CONTROL_SOCKET_TYPE);
+} COLON control_socket_type_value {
+ ctx.stack_.back()->set("socket-type", $4);
ctx.leave();
};
-socket_name: SOCKET_NAME {
+control_socket_type_value:
+ UNIX { $$ = ElementPtr(new StringElement("unix", ctx.loc2pos(@1))); }
+ | HTTP { $$ = ElementPtr(new StringElement("http", ctx.loc2pos(@1))); }
+ | HTTPS { $$ = ElementPtr(new StringElement("https", ctx.loc2pos(@1))); }
+ ;
+
+control_socket_name: SOCKET_NAME {
ctx.unique("socket-name", ctx.loc2pos(@1));
ctx.enter(ctx.NO_KEYWORD);
} COLON STRING {
ctx.leave();
};
+control_socket_address: SOCKET_ADDRESS {
+ ctx.unique("socket-address", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr address(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("socket-address", address);
+ ctx.leave();
+};
+
+control_socket_port: SOCKET_PORT COLON INTEGER {
+ ctx.unique("socket-port", ctx.loc2pos(@1));
+ ElementPtr port(new IntElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("socket-port", port);
+};
+
+cert_required: CERT_REQUIRED COLON BOOLEAN {
+ ctx.unique("cert-required", ctx.loc2pos(@1));
+ ElementPtr req(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("cert-required", req);
+};
+
+// --- authentication ---------------------------------------------
+
+authentication: AUTHENTICATION {
+ ctx.unique("authentication", ctx.loc2pos(@1));
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("authentication", m);
+ ctx.stack_.push_back(m);
+ ctx.enter(ctx.AUTHENTICATION);
+} COLON LCURLY_BRACKET auth_params RCURLY_BRACKET {
+ // The type parameter is required
+ ctx.require("type", ctx.loc2pos(@4), ctx.loc2pos(@6));
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+auth_params: auth_param
+ | auth_params COMMA auth_param
+ | auth_params COMMA {
+ ctx.warnAboutExtraCommas(@2);
+ }
+ ;
+
+auth_param: auth_type
+ | realm
+ | directory
+ | clients
+ | comment
+ | user_context
+ | unknown_map_entry
+ ;
+
+auth_type: TYPE {
+ ctx.unique("type", ctx.loc2pos(@1));
+ ctx.enter(ctx.AUTH_TYPE);
+} COLON auth_type_value {
+ ctx.stack_.back()->set("type", $4);
+ ctx.leave();
+};
+
+auth_type_value: BASIC { $$ = ElementPtr(new StringElement("basic", ctx.loc2pos(@1))); }
+ ;
+
+realm: REALM {
+ ctx.unique("realm", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr realm(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("realm", realm);
+ ctx.leave();
+};
+
+directory: DIRECTORY {
+ ctx.unique("directory", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr directory(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("directory", directory);
+ ctx.leave();
+};
+
+clients: CLIENTS {
+ ctx.unique("clients", ctx.loc2pos(@1));
+ ElementPtr l(new ListElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("clients", l);
+ ctx.stack_.push_back(l);
+ ctx.enter(ctx.CLIENTS);
+} COLON LSQUARE_BRACKET clients_list RSQUARE_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+clients_list: %empty
+ | not_empty_clients_list
+ ;
+
+not_empty_clients_list: basic_auth
+ | not_empty_clients_list COMMA basic_auth
+ | not_empty_clients_list COMMA {
+ ctx.warnAboutExtraCommas(@2);
+ }
+ ;
+
+basic_auth: LCURLY_BRACKET {
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->add(m);
+ ctx.stack_.push_back(m);
+} clients_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+};
+
+clients_params: clients_param
+ | clients_params COMMA clients_param
+ | clients_params COMMA {
+ ctx.warnAboutExtraCommas(@2);
+ }
+ ;
+
+clients_param: user
+ | user_file
+ | password
+ | password_file
+ | user_context
+ | comment
+ | unknown_map_entry
+ ;
+
+user_file: USER_FILE {
+ ctx.unique("user-file", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr user(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("user-file", user);
+ ctx.leave();
+};
+
+password_file: PASSWORD_FILE {
+ ctx.unique("password-file", ctx.loc2pos(@1));
+ ctx.enter(ctx.NO_KEYWORD);
+} COLON STRING {
+ ElementPtr password(new StringElement($4, ctx.loc2pos(@4)));
+ ctx.stack_.back()->set("password-file", password);
+ ctx.leave();
+};
// --- dhcp-queue-control ---------------------------------------------
(config_pair.first == "option-data") ||
(config_pair.first == "mac-sources") ||
(config_pair.first == "control-socket") ||
+ (config_pair.first == "control-sockets") ||
(config_pair.first == "multi-threading") ||
(config_pair.first == "dhcp-queue-control") ||
(config_pair.first == "host-reservation-identifiers") ||
return ("duid-type");
case CONTROL_SOCKET:
return ("control-socket");
+ case CONTROL_SOCKET_TYPE:
+ return ("control-socket-type");
+ case AUTHENTICATION:
+ return ("authentication");
+ case AUTH_TYPE:
+ return ("auth-type");
+ case CLIENTS:
+ return ("clients");
case DHCP_QUEUE_CONTROL:
return ("dhcp-queue-control");
case DHCP_MULTI_THREADING:
/// Used while parsing Dhcp6/control-socket structures.
CONTROL_SOCKET,
+ /// Used while parsing Dhcp6/control-socket/socket-type structures.
+ CONTROL_SOCKET_TYPE,
+
+ /// Used while parsing Dhcp6/control-socket/authentication structures.
+ AUTHENTICATION,
+
+ /// Used while parsing Dhcp6/control-socket/authentication/type
+ /// structures.
+ AUTH_TYPE,
+
+ /// Used while parsing Dhcp6/control-socket/authentication/clients
+ /// structures.
+ CLIENTS,
+
/// Used while parsing Dhcp6/dhcp-queue-control structures.
DHCP_QUEUE_CONTROL,
TEST_F(TrailingCommasTest, tests) {
string txt(R"({
"Dhcp6": {
- "control-socket": {
- "socket-name": "/tmp/kea-dhcp6-ctrl.sock",
- "socket-type": "unix",
- },
+ "control-sockets": [
+ {
+ "socket-type": "http",
+ "socket-address": "::1",
+ "authentication": {
+ "clients": [
+ {
+ "password-file": "/tmp/pwd",
+ }
+ ],
+ "type": "basic",
+ },
+ "socket-port": 8000,
+ },
+ ],
"hooks-libraries": [
{
"library": "/usr/local/lib/kea/hooks/libdhcp_dummy.so",
})");
testParser(txt, Parser6Context::PARSER_DHCP6, false);
- addLog("<string>:5.28");
- addLog("<string>:9.63");
- addLog("<string>:10.8");
- addLog("<string>:14.15");
- addLog("<string>:15.8");
- addLog("<string>:20.24");
- addLog("<string>:28.31");
- addLog("<string>:29.12");
- addLog("<string>:31.28");
- addLog("<string>:32.8");
- addLog("<string>:43.38");
- addLog("<string>:44.12");
- addLog("<string>:47.16");
- addLog("<string>:48.8");
- addLog("<string>:49.6");
- addLog("<string>:50.4");
+ addLog("<string>:10.42");
+ addLog("<string>:13.26");
+ addLog("<string>:15.28");
+ addLog("<string>:16.8");
+ addLog("<string>:20.63");
+ addLog("<string>:21.8");
+ addLog("<string>:25.15");
+ addLog("<string>:26.8");
+ addLog("<string>:31.24");
+ addLog("<string>:39.31");
+ addLog("<string>:40.12");
+ addLog("<string>:42.28");
+ addLog("<string>:43.8");
+ addLog("<string>:54.37");
+ addLog("<string>:55.12");
+ addLog("<string>:58.16");
+ addLog("<string>:59.8");
+ addLog("<string>:60.6");
+ addLog("<string>:61.4");
EXPECT_TRUE(checkFile());
// Test with many consecutive commas.
{ "server-id", Element::map },
{ "dhcp4o6-port", Element::integer },
{ "control-socket", Element::map },
+ { "control-sockets", Element::list },
{ "dhcp-queue-control", Element::map },
{ "dhcp-ddns", Element::map },
{ "user-context", Element::map },