mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2026-01-27 17:17:17 +01:00
Ticket #10024: CWMP dual stack
This commit is contained in:
parent
f0bb411fd1
commit
e99dc20279
19 changed files with 257 additions and 122 deletions
|
|
@ -3,6 +3,8 @@ include:
|
|||
file: '/static-code-analysis.yml'
|
||||
- project: 'docs/portal2/pipeline-template'
|
||||
file: 'MkDocs.gitlab-ci.yml'
|
||||
rules:
|
||||
- if: $CI_COMMIT_BRANCH == "devel"
|
||||
|
||||
variables:
|
||||
DEBUG: 'TRUE'
|
||||
|
|
|
|||
|
|
@ -102,13 +102,6 @@
|
|||
<td class="td_row_odd"><div class="td_row_odd">2000</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">The retry interval multiplier for session retry session as described in the standard.</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_odd"><div class="td_row_odd">ipv6_enable</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">boolean</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">no</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd"></div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">Enables IPv6 in cwmp</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_even"><div class="td_row_even">ssl_capath</div></td>
|
||||
<td class="td_row_even"><div class="td_row_even">string</div></td>
|
||||
|
|
@ -231,13 +224,6 @@
|
|||
<td class="td_row_even"><div class="td_row_even"></div></td>
|
||||
<td class="td_row_even"><div class="td_row_even">Overwrite DeviceId parameter</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_odd"><div class="td_row_odd">default_wan_interface</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">string</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">no</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd"></div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">Configure the default wan interface of the device.</div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="td_row_odd"><div class="td_row_odd">default_lan_interface</div></td>
|
||||
<td class="td_row_odd"><div class="td_row_odd">string</div></td>
|
||||
|
|
|
|||
28
docs/guide/dual_stack_ip.md
Normal file
28
docs/guide/dual_stack_ip.md
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
# Dual Stack IP in icwmp:
|
||||
|
||||
IPv4/IPv6 switch is done automatically in icwmp client. The CPE checks what's the suitable IP protocol (IPv4 or IPv6) to communicate with the ACS respecting those conditions:
|
||||
|
||||
- IPv6 has the priority in the connection
|
||||
- if IPv6 is disabled in the CPE side, so the CPE will automatically switch to IPv4 as IP protocol for the communication with the ACS side.
|
||||
- If the CPE is not able to communicate with the ACS using IPv6, so it switches automatically to IPv4 as an IP protocol.
|
||||
|
||||
This check is done in the beginng of the CWMP session respecting the following algorithm:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[check if IPv6 is enabled in the CPE device] --> B{is enabled?}
|
||||
B -- no -->C[Select IPv4]
|
||||
B -- yes -->D[send an empty HTTP Request to the ACS side]
|
||||
D -->E{get response}
|
||||
E -- succes response -->F[Select IPv6]
|
||||
E -- fail response -->C
|
||||
```
|
||||
|
||||
While the CPE must prioritize the IPv6, so it starts by checking if IPv6 is working in the CPE, then sends a HTTP message to the ACS side through IPv6 before making the same test in IPv4.
|
||||
|
||||
### Dual Stack configuration
|
||||
|
||||
Two uci options are present to configure dual stack:
|
||||
|
||||
- cwmp.cpe.default_wan_interface: that is the network interface that is used to check the connection with IPv4.
|
||||
- cwmp.cpe.default_wan6_interface: that is the network interface that is used to check the connection with IPv6.
|
||||
|
|
@ -11,7 +11,7 @@ exec_cmd apt install -y mongodb jq uuid-dev
|
|||
exec_cmd apt-get install -y libmxml-dev
|
||||
|
||||
# install genieacs
|
||||
exec_cmd npm install -g genieacs@1.2.9
|
||||
exec_cmd npm install -g genieacs@1.2.5
|
||||
ln -sf /root/.nvm/versions/node/v14.16.1/bin/genieacs-cwmp /usr/sbin/genieacs-cwmp
|
||||
ln -sf /root/.nvm/versions/node/v14.16.1/bin/genieacs-fs /usr/sbin/genieacs-fs
|
||||
ln -sf /root/.nvm/versions/node/v14.16.1/bin/genieacs-ui /usr/sbin/genieacs-ui
|
||||
|
|
|
|||
|
|
@ -75,13 +75,6 @@
|
|||
"default": "2000",
|
||||
"description": "The retry interval multiplier for session retry session as described in the standard."
|
||||
},
|
||||
{
|
||||
"name": "ipv6_enable",
|
||||
"type": "boolean",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "Enables IPv6 in cwmp"
|
||||
},
|
||||
{
|
||||
"name": "ssl_capath",
|
||||
"type": "string",
|
||||
|
|
@ -110,13 +103,6 @@
|
|||
"default": "",
|
||||
"description": "the **url** of ACS server received from the DHCP server via Option 43. This parameter is automatically updated by daemon, When **'dhcp_discovery'** option is enabled."
|
||||
},
|
||||
{
|
||||
"name": "ip_version",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "ip_version of ConnectionRequestURL"
|
||||
},
|
||||
{
|
||||
"name": "get_rpc_methods",
|
||||
"type": "boolean",
|
||||
|
|
@ -187,20 +173,27 @@
|
|||
"default": "",
|
||||
"description": "Overwrite DeviceId parameter"
|
||||
},
|
||||
{
|
||||
"name": "default_wan_interface",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"description": "Configure the default wan interface of the device."
|
||||
},
|
||||
{
|
||||
"name": "default_lan_interface",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "",
|
||||
"default": "lan",
|
||||
"description": "Configure the default lan interface of the device."
|
||||
},
|
||||
{
|
||||
"name": "default_wan_interface",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "wan",
|
||||
"description": "Configure the default wan interface that will be used for IPv4 connection."
|
||||
},
|
||||
{
|
||||
"name": "default_wan6_interface",
|
||||
"type": "string",
|
||||
"required": "no",
|
||||
"default": "wan6",
|
||||
"description": "Configure the default wan interface that will be used for IPv6 connection."
|
||||
},
|
||||
{
|
||||
"name": "log_to_console",
|
||||
"type": "string",
|
||||
|
|
|
|||
98
src/common.c
98
src/common.c
|
|
@ -755,25 +755,35 @@ void ubus_network_interface_callback(struct ubus_request *req __attribute__((unu
|
|||
|
||||
// Only update the interface if its not empty
|
||||
if (CWMP_STRLEN(l3_device)) {
|
||||
cwmp_main->conf.interface = strdup(l3_device);
|
||||
cwmp_main->net.interface = strdup(l3_device);
|
||||
}
|
||||
|
||||
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s", cwmp_main->conf.interface);
|
||||
CWMP_LOG(DEBUG, "CWMP IFACE - interface: %s", cwmp_main->net.interface);
|
||||
}
|
||||
|
||||
int get_connection_interface(char *iface)
|
||||
void set_uci_connection_interface(char* interface)
|
||||
{
|
||||
if (iface == NULL)
|
||||
return -1;
|
||||
if (interface == NULL) {
|
||||
CWMP_LOG(WARNING, "%s interface is NULL", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
cwmp_uci_set_varstate_value("cwmp", "cpe", "interface", interface);
|
||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||
}
|
||||
|
||||
int get_connection_interface()
|
||||
{
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
char ubus_obj[100] = {0};
|
||||
snprintf(ubus_obj, sizeof(ubus_obj), "network.interface.%s", iface);
|
||||
if (cwmp_main->net.ipv6_status)
|
||||
snprintf(ubus_obj, sizeof(ubus_obj), "network.interface.%s", cwmp_main->conf.default_wan6_iface);
|
||||
else
|
||||
snprintf(ubus_obj, sizeof(ubus_obj), "network.interface.%s", cwmp_main->conf.default_wan_iface);
|
||||
|
||||
FREE(cwmp_main->conf.interface);
|
||||
FREE(cwmp_main->net.interface);
|
||||
|
||||
int e = icwmp_ubus_invoke(ubus_obj, "status", b.head, ubus_network_interface_callback, NULL);
|
||||
blob_buf_free(&b);
|
||||
|
|
@ -781,12 +791,84 @@ int get_connection_interface(char *iface)
|
|||
if (e != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (cwmp_main->conf.interface == NULL) {
|
||||
if (cwmp_main->net.interface == NULL) {
|
||||
return -1;
|
||||
}
|
||||
set_uci_connection_interface(cwmp_main->net.interface);
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
int get_connection_parameters()
|
||||
{
|
||||
int error = get_connection_interface();
|
||||
if (error != CWMP_OK) {
|
||||
CWMP_LOG(DEBUG, "Failed to get interface [%s] details", cwmp_main->net.connection_wan_iface);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = icwmp_check_http_connection();
|
||||
if (error != CWMP_OK || !cwmp_main->net.connection_wan_iface) {
|
||||
CWMP_LOG(DEBUG, "Failed to check http connection");
|
||||
return error;
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
void ubus_network_interface_status_callback(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
bool *up = (bool *)req->priv;
|
||||
|
||||
const struct blobmsg_policy p[1] = { { "up", BLOBMSG_TYPE_BOOL } };
|
||||
struct blob_attr *tb[1] = { NULL };
|
||||
blobmsg_parse(p, 1, tb, blobmsg_data(msg), blobmsg_len(msg));
|
||||
if (tb[0] != NULL)
|
||||
*up = blobmsg_get_bool(tb[0]);
|
||||
}
|
||||
|
||||
bool check_ipv6_enabled()
|
||||
{
|
||||
bool up=false;
|
||||
struct blob_buf b = { 0 };
|
||||
memset(&b, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&b, 0);
|
||||
|
||||
char ubus_network_interface[512];
|
||||
snprintf(ubus_network_interface, sizeof(ubus_network_interface), "network.interface.%s", cwmp_main->conf.default_wan6_iface);
|
||||
icwmp_ubus_invoke(ubus_network_interface, "status", b.head, ubus_network_interface_status_callback, &up);
|
||||
|
||||
blob_buf_free(&b);
|
||||
|
||||
return up;
|
||||
}
|
||||
|
||||
bool check_connection_attributes_change()
|
||||
{
|
||||
cwmp_uci_reinit();
|
||||
|
||||
char *actual_wan_interface = NULL, *actual_wan6_interface = NULL;
|
||||
uci_get_value("cwmp.cpe.default_wan_interface", &actual_wan_interface);
|
||||
uci_get_value("cwmp.cpe.default_wan6_interface", &actual_wan6_interface);
|
||||
bool wan_interface_changed = CWMP_STRCMP(actual_wan_interface, cwmp_main->conf.default_wan_iface);
|
||||
bool wan6_interface_changed = CWMP_STRCMP(actual_wan6_interface, cwmp_main->conf.default_wan_iface);
|
||||
|
||||
if (wan_interface_changed)
|
||||
{
|
||||
FREE(cwmp_main->conf.default_wan_iface);
|
||||
cwmp_main->conf.default_wan_iface = strdup(actual_wan_interface);
|
||||
}
|
||||
if (wan6_interface_changed)
|
||||
{
|
||||
FREE(cwmp_main->conf.default_wan6_iface);
|
||||
cwmp_main->conf.default_wan6_iface = strdup(actual_wan6_interface);
|
||||
}
|
||||
FREE(actual_wan_interface);
|
||||
FREE(actual_wan6_interface);
|
||||
bool actual_ipv6_status = check_ipv6_enabled();
|
||||
bool ipv6_status_changed = (actual_ipv6_status != cwmp_main->net.ipv6_status);
|
||||
cwmp_main->net.ipv6_status = actual_ipv6_status;
|
||||
return ipv6_status_changed || wan_interface_changed || wan6_interface_changed;
|
||||
}
|
||||
|
||||
char *get_time(time_t t_time)
|
||||
{
|
||||
static char local_time[32] = {0};
|
||||
|
|
|
|||
22
src/common.h
22
src/common.h
|
|
@ -22,6 +22,8 @@
|
|||
#include <libubox/list.h>
|
||||
#include <pthread.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifndef FREE
|
||||
#define FREE(x) do { if(x) {free(x); x = NULL;} } while (0)
|
||||
|
|
@ -31,7 +33,7 @@
|
|||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
#define CWMP_STRCMP(S1, S2) ((S1 != NULL && S2 != NULL) ? strcmp(S1, S2) : -1)
|
||||
#define CWMP_STRCMP(S1, S2) ((S1 != NULL && S2 != NULL) ? strcmp(S1, S2) : (S1 == S2))
|
||||
#define CWMP_STRDUP(S1) ((S1 != NULL) ? strdup(S1) : NULL)
|
||||
#define CWMP_STRLEN(S1) ((S1 != NULL) ? strlen(S1) : 0)
|
||||
|
||||
|
|
@ -87,6 +89,13 @@ typedef struct env {
|
|||
long int max_firmware_size;
|
||||
} env;
|
||||
|
||||
struct connection {
|
||||
char *connection_wan_iface;
|
||||
char *interface;
|
||||
int ip_resolve;
|
||||
bool ipv6_status;
|
||||
};
|
||||
|
||||
typedef struct config {
|
||||
char *acsurl;
|
||||
char *acs_userid;
|
||||
|
|
@ -97,17 +106,16 @@ typedef struct config {
|
|||
char *custom_notify_json;
|
||||
char *ip;
|
||||
char *ipv6;
|
||||
char *interface;
|
||||
char *ubus_socket;
|
||||
char *default_wan_iface;
|
||||
char *connection_request_path;
|
||||
char *auto_tc_transfer_type;
|
||||
char *auto_tc_result_type;
|
||||
char *auto_tc_file_type;
|
||||
|
||||
char *auto_cdu_oprt_type;
|
||||
char *auto_cdu_result_type;
|
||||
char *auto_cdu_fault_code;
|
||||
char *default_wan_iface;
|
||||
char *default_wan6_iface;
|
||||
int connection_request_port;
|
||||
int period;
|
||||
int periodic_notify_interval;
|
||||
|
|
@ -124,7 +132,6 @@ typedef struct config {
|
|||
bool periodic_enable;
|
||||
bool periodic_notify_enable;
|
||||
bool insecure_enable;
|
||||
bool ipv6_enable;
|
||||
bool heart_beat_enable;
|
||||
bool acs_getrpc;
|
||||
bool auto_tc_enable;
|
||||
|
|
@ -153,6 +160,7 @@ typedef struct cwmp {
|
|||
struct env env;
|
||||
struct config conf;
|
||||
struct deviceid deviceid;
|
||||
struct connection net;
|
||||
struct session *session;
|
||||
bool cwmp_cr_event;
|
||||
bool init_complete;
|
||||
|
|
@ -606,6 +614,10 @@ bool icwmp_validate_int_in_range(char *arg, int min, int max);
|
|||
char *string_to_hex(const unsigned char *str, size_t size);
|
||||
int copy_file(char *source_file, char *target_file);
|
||||
int get_connection_interface();
|
||||
int get_connection_parameters();
|
||||
int icwmp_check_http_connection();
|
||||
bool check_ipv6_enabled();
|
||||
bool check_connection_attributes_change();
|
||||
char *get_time(time_t t_time);
|
||||
bool is_obj_excluded(const char *object_name);
|
||||
bool is_reload_parameter(const char *object_name);
|
||||
|
|
|
|||
25
src/config.c
25
src/config.c
|
|
@ -48,6 +48,7 @@ static void config_get_cpe_elements(struct uci_section *s)
|
|||
UCI_CPE_ENABLE_SYSLOG,
|
||||
UCI_CPE_AMD_VERSION,
|
||||
UCI_CPE_DEFAULT_WAN_IFACE,
|
||||
UCI_CPE_DEFAULT_WAN6_IFACE,
|
||||
__MAX_NUM_UCI_CPE_ATTRS,
|
||||
};
|
||||
|
||||
|
|
@ -61,6 +62,7 @@ static void config_get_cpe_elements(struct uci_section *s)
|
|||
{ .name = "log_to_syslog", .type = UCI_TYPE_STRING },
|
||||
{ .name = "amd_version", .type = UCI_TYPE_STRING },
|
||||
{ .name = "default_wan_interface", .type = UCI_TYPE_STRING },
|
||||
{ .name = "default_wan6_interface", .type = UCI_TYPE_STRING },
|
||||
};
|
||||
|
||||
struct uci_option *cpe_tb[__MAX_NUM_UCI_CPE_ATTRS] = {0};
|
||||
|
|
@ -91,18 +93,23 @@ static void config_get_cpe_elements(struct uci_section *s)
|
|||
}
|
||||
cwmp_main->conf.supported_amd_version = cwmp_main->conf.amd_version;
|
||||
CWMP_LOG(DEBUG, "CWMP CONFIG - amendement version: %d", cwmp_main->conf.amd_version);
|
||||
if (cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]) {
|
||||
|
||||
if (cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE])
|
||||
cwmp_main->conf.default_wan_iface = strdup(get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN_IFACE]));
|
||||
} else {
|
||||
else
|
||||
cwmp_main->conf.default_wan_iface = strdup("wan");
|
||||
}
|
||||
CWMP_LOG(DEBUG, "CWMP CONFIG - default wan interface: %s", cwmp_main->conf.default_wan_iface);
|
||||
|
||||
if (cpe_tb[UCI_CPE_DEFAULT_WAN6_IFACE])
|
||||
cwmp_main->conf.default_wan6_iface = strdup(get_value_from_uci_option(cpe_tb[UCI_CPE_DEFAULT_WAN6_IFACE]));
|
||||
else
|
||||
cwmp_main->conf.default_wan6_iface = strdup("wan6");
|
||||
CWMP_LOG(DEBUG, "CWMP CONFIG - default wan ipv6 interface: %s", cwmp_main->conf.default_wan6_iface);
|
||||
}
|
||||
|
||||
static void config_get_acs_elements(struct uci_section *s)
|
||||
{
|
||||
enum {
|
||||
UCI_ACS_IPV6_ENABLE,
|
||||
UCI_ACS_SSL_CAPATH,
|
||||
HTTP_DISABLE_100CONTINUE,
|
||||
UCI_ACS_INSECURE_ENABLE,
|
||||
|
|
@ -110,7 +117,6 @@ static void config_get_acs_elements(struct uci_section *s)
|
|||
};
|
||||
|
||||
const struct uci_parse_option acs_opts[] = {
|
||||
{ .name = "ipv6_enable", .type = UCI_TYPE_STRING },
|
||||
{ .name = "ssl_capath", .type = UCI_TYPE_STRING },
|
||||
{ .name = "http_disable_100continue", .type = UCI_TYPE_STRING },
|
||||
{ .name = "insecure_enable", .type = UCI_TYPE_STRING },
|
||||
|
|
@ -120,9 +126,6 @@ static void config_get_acs_elements(struct uci_section *s)
|
|||
memset(acs_tb, 0, sizeof(acs_tb));
|
||||
uci_parse_section(s, acs_opts, __MAX_NUM_UCI_ACS_ATTRS, acs_tb);
|
||||
|
||||
cwmp_main->conf.ipv6_enable = uci_str_to_bool(get_value_from_uci_option(acs_tb[UCI_ACS_IPV6_ENABLE]));
|
||||
CWMP_LOG(DEBUG, "CWMP CONFIG - ipv6 enable: %d", cwmp_main->conf.ipv6_enable);
|
||||
|
||||
cwmp_main->conf.acs_ssl_capath = CWMP_STRDUP(get_value_from_uci_option(acs_tb[UCI_ACS_SSL_CAPATH]));
|
||||
CWMP_LOG(DEBUG, "CWMP CONFIG - acs ssl cpath: %s", cwmp_main->conf.acs_ssl_capath ? cwmp_main->conf.acs_ssl_capath : "");
|
||||
|
||||
|
|
@ -188,12 +191,6 @@ int get_global_config()
|
|||
}
|
||||
FREE(value);
|
||||
|
||||
error = get_connection_interface(cwmp_main->conf.default_wan_iface);
|
||||
if (error != CWMP_OK) {
|
||||
CWMP_LOG(DEBUG, "Failed to get interface [%s] details", cwmp_main->conf.default_wan_iface);
|
||||
return error;
|
||||
}
|
||||
|
||||
bool discovery_enable = false;
|
||||
error = uci_get_value(UCI_DHCP_DISCOVERY_PATH, &value);
|
||||
if (error == CWMP_OK && value != NULL) {
|
||||
|
|
|
|||
17
src/cwmp.c
17
src/cwmp.c
|
|
@ -205,6 +205,8 @@ static int cwmp_init()
|
|||
|
||||
cwmp_main = (struct cwmp*)calloc(1, sizeof(struct cwmp));
|
||||
cwmp_main->init_complete = false;
|
||||
cwmp_main->net.interface = NULL;
|
||||
cwmp_main->net.connection_wan_iface = NULL;
|
||||
error = get_preinit_config();
|
||||
if (error) {
|
||||
return error;
|
||||
|
|
@ -276,6 +278,13 @@ static int cwmp_init()
|
|||
cwmp_main->cwmp_period = 0;
|
||||
cwmp_main->cwmp_periodic_time = 0;
|
||||
cwmp_main->cwmp_periodic_enable = false;
|
||||
sleep(15);
|
||||
cwmp_main->net.ipv6_status = check_ipv6_enabled();
|
||||
error = get_connection_parameters();
|
||||
if (error != CWMP_OK) {
|
||||
CWMP_LOG(DEBUG, "Failed to get connection parameters");
|
||||
return error;
|
||||
}
|
||||
return CWMP_OK;
|
||||
}
|
||||
|
||||
|
|
@ -293,12 +302,12 @@ static void cwmp_free()
|
|||
FREE(cwmp_main->conf.acsurl);
|
||||
FREE(cwmp_main->conf.acs_userid);
|
||||
FREE(cwmp_main->conf.acs_passwd);
|
||||
FREE(cwmp_main->conf.interface);
|
||||
FREE(cwmp_main->net.interface);
|
||||
FREE(cwmp_main->conf.cpe_userid);
|
||||
FREE(cwmp_main->conf.cpe_passwd);
|
||||
FREE(cwmp_main->conf.ubus_socket);
|
||||
FREE(cwmp_main->conf.connection_request_path);
|
||||
FREE(cwmp_main->conf.default_wan_iface);
|
||||
FREE(cwmp_main->net.connection_wan_iface);
|
||||
FREE(cwmp_main->conf.custom_notify_json);
|
||||
FREE(cwmp_main->conf.auto_cdu_fault_code);
|
||||
FREE(cwmp_main->conf.auto_cdu_oprt_type);
|
||||
|
|
@ -306,6 +315,8 @@ static void cwmp_free()
|
|||
FREE(cwmp_main->conf.auto_tc_file_type);
|
||||
FREE(cwmp_main->conf.auto_tc_result_type);
|
||||
FREE(cwmp_main->conf.auto_tc_transfer_type);
|
||||
FREE(cwmp_main->conf.default_wan_iface);
|
||||
FREE(cwmp_main->conf.default_wan6_iface);
|
||||
FREE(nonce_key);
|
||||
clean_list_param_notify();
|
||||
bkp_tree_clean();
|
||||
|
|
@ -352,7 +363,7 @@ static void configure_var_state()
|
|||
cwmp_uci_add_section_with_specific_name("cwmp", "acs", "acs", UCI_VARSTATE_CONFIG);
|
||||
cwmp_uci_add_section_with_specific_name("cwmp", "cpe", "cpe", UCI_VARSTATE_CONFIG);
|
||||
|
||||
get_firewall_zone_name_by_wan_iface(cwmp_main->conf.default_wan_iface, &zone_name);
|
||||
get_firewall_zone_name_by_wan_iface(cwmp_main->net.connection_wan_iface, &zone_name);
|
||||
cwmp_uci_set_varstate_value("cwmp", "acs", "zonename", zone_name ? zone_name : "wan");
|
||||
|
||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||
|
|
|
|||
|
|
@ -457,10 +457,10 @@ static void get_management_ip_port(char **listen_addr)
|
|||
{
|
||||
char *ip = NULL, *port = NULL, *interface = NULL, *if_name = NULL, *version = NULL;
|
||||
|
||||
dmuci_get_option_value_string("cwmp", "cpe", "default_wan_interface", &interface);
|
||||
dmuci_get_option_value_string("cwmp", "cpe", "interface", &if_name);
|
||||
dmuci_get_option_value_string("cwmp", "acs", "ip_version", &version);
|
||||
dmuci_get_option_value_string_varstate("cwmp", "cpe", "interface", &if_name);
|
||||
dmuci_get_option_value_string_varstate("cwmp", "acs", "ip_version", &version);
|
||||
dmuci_get_option_value_string("cwmp", "cpe", "port", &port);
|
||||
dmuci_get_option_value_string("cwmp", "cpe", *version == '6' ? "default_wan6_interface" : "default_wan_interface", &interface);
|
||||
|
||||
if (network_get_ipaddr(interface, *version == '6' ? 6 : 4, &ip) == -1) {
|
||||
if (if_name[0] == '\0')
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "cwmp_http.h"
|
||||
#include "http.h"
|
||||
#include "log.h"
|
||||
#include "cwmp_uci.h"
|
||||
|
||||
struct uloop_fd http_event6;
|
||||
|
||||
|
|
@ -49,3 +50,57 @@ void http_server_stop(void)
|
|||
{
|
||||
pthread_join(http_cr_server_thread, NULL);
|
||||
}
|
||||
|
||||
void set_http_ip_resolve(int resolve)
|
||||
{
|
||||
cwmp_uci_set_varstate_value("cwmp", "acs", "ip_version", (resolve == CURL_IPRESOLVE_V6) ? "6" : "4");
|
||||
cwmp_commit_package("cwmp", UCI_VARSTATE_CONFIG);
|
||||
FREE(cwmp_main->net.connection_wan_iface);
|
||||
cwmp_main->net.connection_wan_iface = strdup((resolve == CURL_IPRESOLVE_V6) ? cwmp_main->conf.default_wan6_iface : cwmp_main->conf.default_wan_iface);
|
||||
cwmp_main->net.ip_resolve = resolve;
|
||||
}
|
||||
|
||||
int icwmp_check_http_connection()
|
||||
{
|
||||
if (!cwmp_main->net.ipv6_status) {
|
||||
set_http_ip_resolve(CURL_IPRESOLVE_V4);
|
||||
return CWMP_OK;
|
||||
}
|
||||
long resolve = CURL_IPRESOLVE_V6;
|
||||
while(1) {
|
||||
CURL *c = curl_easy_init();
|
||||
if(c) {
|
||||
CURLcode ret;
|
||||
curl_easy_setopt(c, CURLOPT_FAILONERROR, true);
|
||||
curl_easy_setopt(c, CURLOPT_URL, cwmp_main->conf.acsurl);
|
||||
curl_easy_setopt(c, CURLOPT_CONNECT_ONLY, 1L);
|
||||
curl_easy_setopt(c, CURLOPT_IPRESOLVE, resolve);
|
||||
curl_easy_setopt(c, CURLOPT_INTERFACE, cwmp_main->net.interface);
|
||||
ret = curl_easy_perform(c);
|
||||
if(ret == CURLE_OK) {
|
||||
int tmp = 1;
|
||||
char *ip = NULL;
|
||||
curl_easy_getinfo(c, CURLINFO_PRIMARY_IP, &ip);
|
||||
if (ip) {
|
||||
unsigned char buf[sizeof(struct in6_addr)];
|
||||
tmp = inet_pton(AF_INET, ip, buf);
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
set_http_ip_resolve(CURL_IPRESOLVE_V4);
|
||||
else
|
||||
set_http_ip_resolve(CURL_IPRESOLVE_V6);
|
||||
curl_easy_cleanup(c);
|
||||
return CWMP_OK;
|
||||
}
|
||||
curl_easy_cleanup(c);
|
||||
}
|
||||
if (resolve == CURL_IPRESOLVE_V6)
|
||||
resolve = CURL_IPRESOLVE_V4;
|
||||
else if (resolve == CURL_IPRESOLVE_V4)
|
||||
resolve = CURL_IPRESOLVE_WHATEVER;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
49
src/http.c
49
src/http.c
|
|
@ -10,7 +10,6 @@
|
|||
* See LICENSE file for license related information.
|
||||
*
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -42,58 +41,17 @@ void http_set_timeout(void)
|
|||
|
||||
int icwmp_http_client_init()
|
||||
{
|
||||
char *dhcp_dis = NULL;
|
||||
char *acs_var_stat = NULL;
|
||||
|
||||
uci_get_value(UCI_DHCP_DISCOVERY_PATH, &dhcp_dis);
|
||||
|
||||
if (dhcp_dis && cwmp_main->retry_count_session > 0 && strcmp(dhcp_dis, "enable") == 0) {
|
||||
uci_get_state_value(UCI_DHCP_ACS_URL, &acs_var_stat);
|
||||
if (acs_var_stat) {
|
||||
if (icwmp_asprintf(&http_c.url, "%s", acs_var_stat) == -1) {
|
||||
free(acs_var_stat);
|
||||
FREE(dhcp_dis);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (cwmp_main->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp_main->conf.acsurl) == -1) {
|
||||
FREE(dhcp_dis);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (cwmp_main->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp_main->conf.acsurl) == -1) {
|
||||
FREE(dhcp_dis);
|
||||
return -1;
|
||||
}
|
||||
if (cwmp_main->conf.acsurl == NULL || icwmp_asprintf(&http_c.url, "%s", cwmp_main->conf.acsurl) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dhcp_dis)
|
||||
free(dhcp_dis);
|
||||
|
||||
CWMP_LOG(INFO, "ACS url: %s", http_c.url);
|
||||
|
||||
/* TODO debug ssl config from freecwmp*/
|
||||
|
||||
curl_global_init(CURL_GLOBAL_SSL);
|
||||
curl = curl_easy_init();
|
||||
if (!curl)
|
||||
return -1;
|
||||
|
||||
if (cwmp_main->conf.ipv6_enable) {
|
||||
unsigned char buf[sizeof(struct in6_addr)];
|
||||
|
||||
char *ip = NULL;
|
||||
curl_easy_setopt(curl, CURLOPT_URL, http_c.url);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_TIMEOUT);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
|
||||
curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ip);
|
||||
curl_easy_perform(curl);
|
||||
int tmp = inet_pton(AF_INET, ip, buf);
|
||||
|
||||
cwmp_uci_set_value("cwmp", "acs", "ip_version", (tmp == 1) ? "4" : "6");
|
||||
cwmp_commit_package("cwmp", UCI_STANDARD_CONFIG);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +117,7 @@ static void http_set_connection_options()
|
|||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);
|
||||
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, cwmp_main->net.ip_resolve);
|
||||
#ifdef DEVEL
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
#endif
|
||||
|
|
@ -166,7 +125,7 @@ static void http_set_connection_options()
|
|||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, fc_cookies);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEJAR, fc_cookies);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_INTERFACE, cwmp_main->conf.interface);
|
||||
curl_easy_setopt(curl, CURLOPT_INTERFACE, cwmp_main->net.interface);
|
||||
}
|
||||
|
||||
static void http_set_header_list_options()
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef _FREECWMP_HTTP_H__
|
||||
#define _FREECWMP_HTTP_H__
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern char *fc_cookies;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ char *default_active_notifications_parameters[] = {
|
|||
};
|
||||
|
||||
char *forced_notifications_parameters[] = {
|
||||
"Device.DeviceInfo.SoftwareVersion",
|
||||
"Device.DeviceInfo.ProvisioningCode"
|
||||
"Device.DeviceInfo.SoftwareVersion",
|
||||
"Device.DeviceInfo.ProvisioningCode"
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "heartbeat.h"
|
||||
#include "sched_inform.h"
|
||||
#include "cwmp_du_state.h"
|
||||
#include "cwmp_http.h"
|
||||
|
||||
pthread_mutex_t cwmp_session_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
|
@ -335,6 +336,14 @@ void start_cwmp_session()
|
|||
|
||||
if (cwmp_main->session->session_status.last_status == SESSION_FAILURE)
|
||||
cwmp_config_load();
|
||||
|
||||
if (check_connection_attributes_change()) {
|
||||
if (get_connection_parameters() != CWMP_OK || cwmp_stop) {
|
||||
CWMP_LOG(INFO, "cwmp fails to get connection parameters");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Value changes
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,4 +33,4 @@ all: libunit ${UNIT_TESTS}
|
|||
clean:
|
||||
rm -fv *.o libicwmp.so ${UNIT_TESTS}
|
||||
|
||||
.PHONY: clean unit-test
|
||||
.PHONY: clean unit-test
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ static int dm_iface_unit_tests_clean(void **state)
|
|||
FREE(cwmp_main->conf.acsurl);
|
||||
FREE(cwmp_main->conf.acs_userid);
|
||||
FREE(cwmp_main->conf.acs_passwd);
|
||||
FREE(cwmp_main->conf.interface);
|
||||
FREE(cwmp_main->conf.cpe_userid);
|
||||
FREE(cwmp_main->conf.cpe_passwd);
|
||||
FREE(cwmp_main->conf.ubus_socket);
|
||||
FREE(cwmp_main->conf.connection_request_path);
|
||||
FREE(cwmp_main->conf.default_wan_iface);
|
||||
FREE(cwmp_main->conf.default_wan6_iface);
|
||||
FREE(cwmp_main->conf.custom_notify_json);
|
||||
cwmp_free_all_list_param_fault(&faults_array);
|
||||
cwmp_free_all_dm_parameter_list(&list_set_param_value);
|
||||
|
|
|
|||
|
|
@ -50,12 +50,12 @@ static void clean_config()
|
|||
FREE(cwmp_main->conf.acsurl);
|
||||
FREE(cwmp_main->conf.acs_userid);
|
||||
FREE(cwmp_main->conf.acs_passwd);
|
||||
FREE(cwmp_main->conf.interface);
|
||||
FREE(cwmp_main->conf.cpe_userid);
|
||||
FREE(cwmp_main->conf.cpe_passwd);
|
||||
FREE(cwmp_main->conf.ubus_socket);
|
||||
FREE(cwmp_main->conf.connection_request_path);
|
||||
FREE(cwmp_main->conf.default_wan_iface);
|
||||
FREE(cwmp_main->conf.default_wan6_iface);
|
||||
}
|
||||
|
||||
static void clean_name_space()
|
||||
|
|
|
|||
|
|
@ -11,14 +11,13 @@ config acs 'acs'
|
|||
option retry_min_wait_interval '5'
|
||||
# possible configs interval :[1000:65535]
|
||||
option retry_interval_multiplier '2000'
|
||||
option ipv6_enable '0'
|
||||
option ip_version '4'
|
||||
|
||||
|
||||
config cpe 'cpe'
|
||||
option enable '1'
|
||||
option interface 'eth0'
|
||||
option default_wan_interface 'wan'
|
||||
option default_wan6_interface 'wan6'
|
||||
option log_to_console 'disable'
|
||||
option log_to_syslog 'disable'
|
||||
option log_to_file 'enable'
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue