diff --git a/bin/Makefile.am b/bin/Makefile.am index 35c2179..19645c5 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -17,6 +17,7 @@ icwmpd_SOURCES = \ ../time.c \ ../ubus.c \ ../xml.c \ + ../zlib.c \ ../dm/dmcwmp.c \ ../dm/dmentry.c \ ../dm/dmmem.c \ @@ -72,7 +73,8 @@ icwmpd_LDADD = \ $(LIBZSTREAM_LIBS) \ $(LIBPTHREAD_LIBS) \ $(LIBJSON_LIBS) \ - $(LBLOBMSG_LIBS) + $(LBLOBMSG_LIBS) \ + $(LIBZ_LIBS) icwmpd_CFLAGS+=-DCWMP_VERSION=\"$(CWMP_VERSION)\" icwmpd_LDFLAGS+=-DCWMP_VERSION=\"$(CWMP_VERSION)\" diff --git a/config.c b/config.c index a30e4cc..257f4d8 100644 --- a/config.c +++ b/config.c @@ -495,6 +495,25 @@ int get_global_config(struct config *conf) { return error; } + if((error = uci_get_value(UCI_ACS_COMPRESSION ,&value)) == CWMP_OK) + { + if(value != NULL) + { + if (0 == strcasecmp(value, "gzip")) { + conf->compression = COMP_GZIP; + } else if (0 == strcasecmp(value, "deflate")) { + conf->compression = COMP_DEFLATE; + } else { + conf->compression = COMP_NONE; + } + free(value); + value = NULL; + } + } + else + { + return error; + } if((error = uci_get_value(UCI_ACS_SSL_CAPATH,&value)) == CWMP_OK) { if(value != NULL) diff --git a/configure.ac b/configure.ac index 3eadd8d..68ccbf7 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +32,8 @@ AM_PROG_CC_C_O LIBPTHREAD_LIBS='-lpthread' AC_SUBST([LIBPTHREAD_LIBS]) +LIBZ_LIBS='-lz' +AC_SUBST([LIBZ_LIBS]) case "$CFLAGS" in *_AADJ*) LIBJSON_LIBS='-ljson -ljson-c' ;; *) LIBJSON_LIBS='-ljson' ;; diff --git a/dm/dmtree/managementserver.c b/dm/dmtree/managementserver.c index 816b82d..a551611 100644 --- a/dm/dmtree/managementserver.c +++ b/dm/dmtree/managementserver.c @@ -221,6 +221,34 @@ int set_management_server_connection_request_passwd(char *refparam, struct dmctx return 0; } +int get_management_server_http_compression_supportted(char *refparam, struct dmctx *ctx, char **value) +{ + *value = "GZIP,Deflate"; + return 0; +} + +int get_management_server_http_compression(char *refparam, struct dmctx *ctx, char **value) +{ + dmuci_get_option_value_string("cwmp", "acs", "compression", value); + return 0; +} + +int set_management_server_http_compression(char *refparam, struct dmctx *ctx, int action, char *value) +{ + switch (action) { + case VALUECHECK: + if (0 == strcasecmp(value, "gzip") || 0 == strcasecmp(value, "deflate")) { + return 0; + } + return FAULT_9007; + case VALUESET: + dmuci_set_value("cwmp", "acs", "compression", value); + cwmp_set_end_session(END_SESSION_RELOAD); + return 0; + } + return 0; +} + int entry_method_root_ManagementServer(struct dmctx *ctx) { IF_MATCH(ctx, DMROOT"ManagementServer.") { @@ -235,6 +263,8 @@ int entry_method_root_ManagementServer(struct dmctx *ctx) DMPARAM("ConnectionRequestURL", ctx, "0", get_management_server_connection_request_url, NULL, NULL, 1, 0, 2, NULL); DMPARAM("ConnectionRequestUsername", ctx, "1", get_management_server_connection_request_username, set_management_server_connection_request_username, NULL, 0, 1, UNDEF, NULL); DMPARAM("ConnectionRequestPassword", ctx, "1", get_empty, set_management_server_connection_request_passwd, NULL, 0, 1, UNDEF, NULL); + DMPARAM("HTTPCompressionSupported", ctx, "0", get_management_server_http_compression_supportted, NULL, NULL, 0, 1, UNDEF, NULL); + DMPARAM("HTTPCompression", ctx, "1", get_management_server_http_compression, set_management_server_http_compression, NULL, 0, 1, UNDEF, NULL); return 0; } return FAULT_9005; diff --git a/dm/dmtree/wandevice.c b/dm/dmtree/wandevice.c index 8e32ca9..5cd34bd 100644 --- a/dm/dmtree/wandevice.c +++ b/dm/dmtree/wandevice.c @@ -2219,7 +2219,7 @@ inline int entry_wandevice_wanprotocolconnection_instance(struct dmctx *ctx, cha DMPARAM("X_BROADCOM_COM_FirewallEnabled", ctx, "1", get_interface_firewall_enabled_wanproto, set_interface_firewall_enabled_wanproto, "xsd:boolean", 0, 1, UNDEF, NULL); DMPARAM("X_BROADCOM_COM_IGMPEnabled", ctx, "1", get_wan_ip_link_connection_igmp_enabled, set_wan_ip_link_connection_igmp_enabled, "xsd:boolean", 0, 1, UNDEF, NULL); DMPARAM("DNSEnabled", ctx, "1", get_wan_ip_link_connection_dns_enabled, set_wan_ip_link_connection_dns_enabled, "xsd:boolean", 0, 1, UNDEF, NULL); - DMPARAM("DNSOverrideAllowed", ctx, 0, get_empty, NULL, NULL, 0, 1, UNDEF, NULL); + DMPARAM("DNSOverrideAllowed", ctx, "0", get_empty, NULL, NULL, 0, 1, UNDEF, NULL); DMPARAM("Name", ctx, "1", get_wan_ip_link_connection_name, set_wan_ip_link_connection_connection_name, NULL, 0, 1, UNDEF, NULL); DMOBJECT(DMROOT"WANDevice.%s.WANConnectionDevice.%s.WANIPConnection.%s.X_INTENO_COM_VLAN.", ctx, "1", 1, NULL, NULL, NULL, idev, iwan, iconp); DMPARAM("VLANID", ctx, "1", get_wan_ip_link_connection_vid, set_wan_ip_link_connection_vid, "xsd:unsignedInt", 0, 1, UNDEF, NULL); diff --git a/http.c b/http.c index 5ffffcb..937cf3e 100644 --- a/http.c +++ b/http.c @@ -22,7 +22,6 @@ #include #include "cwmp.h" #include "log.h" - #include #include @@ -74,16 +73,6 @@ http_client_init(struct cwmp *cwmp) /* TODO debug ssl config from freecwmp*/ #ifdef HTTP_CURL - http_c.header_list = NULL; - http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: cwmp"); - if (!http_c.header_list) return -1; - http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/xml"); - if (!http_c.header_list) return -1; -# ifdef ACS_FUSION - char *expect_header = "Expect:"; - http_c.header_list = curl_slist_append(http_c.header_list, expect_header); - if (!http_c.header_list) return -1; -# endif /* ACS_FUSION */ curl = curl_easy_init(); if (!curl) return -1; @@ -155,7 +144,7 @@ http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in) #endif /* HTTP_CURL */ int -http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in) +http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len,char **msg_in) { #ifdef HTTP_CURL CURLcode res; @@ -163,18 +152,38 @@ http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in) static char *ip_acs = NULL; char *ip = NULL; char errbuf[CURL_ERROR_SIZE]; + http_c.header_list = NULL; + http_c.header_list = curl_slist_append(http_c.header_list, "User-Agent: inteno-cwmp"); + if (!http_c.header_list) return -1; + http_c.header_list = curl_slist_append(http_c.header_list, "Content-Type: text/xml"); + if (!http_c.header_list) return -1; +# ifdef ACS_FUSION + char *expect_header = "Expect:"; + http_c.header_list = curl_slist_append(http_c.header_list, expect_header); + if (!http_c.header_list) return -1; +# endif /* ACS_FUSION */ curl_easy_setopt(curl, CURLOPT_URL, http_c.url); curl_easy_setopt(curl, CURLOPT_USERNAME, cwmp->conf.acs_userid); curl_easy_setopt(curl, CURLOPT_PASSWORD, cwmp->conf.acs_passwd); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list); curl_easy_setopt(curl, CURLOPT_TIMEOUT, HTTP_TIMEOUT); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, HTTP_TIMEOUT); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + switch (cwmp->conf.compression) { + case COMP_GZIP: + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "gzip"); + http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: gzip"); + break; + case COMP_DEFLATE: + curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "deflate"); + http_c.header_list = curl_slist_append(http_c.header_list, "Content-Encoding: deflate"); + break; + } + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, http_c.header_list); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, msg_out); if (msg_out) - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) strlen(msg_out)); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) msg_out_len); else curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0); @@ -225,18 +234,26 @@ http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in) } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); - if(http_code == 204) { CWMP_LOG (INFO,"Receive HTTP 204 No Content"); } + if(http_code == 415) + { + cwmp->conf.compression = COMP_NONE; + goto error; + } if (http_code != 200 && http_code != 204) goto error; /* TODO add check for 301, 302 and 307 HTTP Redirect*/ curl_easy_reset(curl); + if (http_c.header_list) { + curl_slist_free_all(http_c.header_list); + http_c.header_list = NULL; + } if (res) goto error; @@ -281,6 +298,10 @@ http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in) error: FREE(*msg_in); + if (http_c.header_list) { + curl_slist_free_all(http_c.header_list); + http_c.header_list = NULL; + } return -1; } diff --git a/inc/cwmp.h b/inc/cwmp.h index 3eac581..d100e24 100644 --- a/inc/cwmp.h +++ b/inc/cwmp.h @@ -43,6 +43,7 @@ #define UCI_ACS_SSL_CAPATH "cwmp.acs.ssl_capath" #define UCI_ACS_INSECURE_ENABLE "cwmp.acs.insecure_enable" #define UCI_ACS_SSL_VERSION "cwmp.acs.ssl_version" +#define UCI_ACS_COMPRESSION "cwmp.acs.compression" #define UCI_LOG_SEVERITY_PATH "cwmp.cpe.log_severity" #define UCI_CPE_USERID_PATH "cwmp.cpe.userid" #define UCI_CPE_PASSWD_PATH "cwmp.cpe.passwd" @@ -106,6 +107,11 @@ enum event_idx_enum { EVENT_IDX_M_Upload, __EVENT_IDX_MAX }; +enum http_compression { + COMP_NONE, + COMP_GZIP, + COMP_DEFLATE +}; typedef struct event_container { struct list_head list; @@ -137,6 +143,7 @@ typedef struct config { char *ubus_socket; int connection_request_port; int period; + int compression; time_t time; bool periodic_enable; bool insecure_enable; @@ -248,5 +255,6 @@ void connection_request_port_value_change(struct cwmp *cwmp, int port); void add_dm_parameter_tolist(struct list_head *head, char *param_name, char *param_data, char *param_type); void cwmp_set_end_session (unsigned int end_session_flag); void *thread_handle_notify(void *v); +int zlib_compress (char *message, unsigned char **zmsg, int *zlen, int type); #endif /* _CWMP_H__ */ diff --git a/inc/http.h b/inc/http.h index e54012f..b42cdae 100644 --- a/inc/http.h +++ b/inc/http.h @@ -47,7 +47,7 @@ static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **m int http_client_init(struct cwmp *cwmp); void http_client_exit(void); -int http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in); +int http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len,char **msg_in); void http_server_init(void); void http_server_listen(void); diff --git a/log.c b/log.c index a063028..127703d 100644 --- a/log.c +++ b/log.c @@ -89,9 +89,8 @@ int log_set_on_file(char *value) void puts_log(int severity, const char *fmt, ...) { va_list args; + int buflen = 1024; int i; - char buf[1024]; - char buf_file[1024]; time_t t; struct tm *Tm; struct timeval tv; @@ -104,6 +103,12 @@ void puts_log(int severity, const char *fmt, ...) { return; } + if (severity == DEBUG) + { + buflen = 512000; + } + char buf[buflen]; + char buf_file[buflen]; gettimeofday(&tv, 0); t = time((time_t*)NULL); @@ -116,15 +121,13 @@ void puts_log(int severity, const char *fmt, ...) Tm->tm_min, Tm->tm_sec, SEVERITY_NAMES[severity]); - if(strlen(log_file_name) == 0) { strcpy(log_file_name,DEFAULT_LOG_FILE_NAME); } - if(enable_log_file) { - pthread_mutex_lock (&mutex_log); + pthread_mutex_lock (&mutex_log); if (stat(log_file_name, &st) == 0) { size = st.st_size; @@ -140,12 +143,11 @@ void puts_log(int severity, const char *fmt, ...) pLog = fopen(log_file_name,"a+"); } } - va_start(args, fmt); i += vsprintf(buf+i, fmt, args); if(enable_log_file) { - sprintf(buf_file,"%s\n",buf); + sprintf(buf_file,"%s\n",buf); fputs (buf_file, pLog); } va_end(args); diff --git a/xml.c b/xml.c index edf6803..4b050c6 100644 --- a/xml.c +++ b/xml.c @@ -168,16 +168,31 @@ void xml_exit(void) int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc) { char *s, *c, *msg_out = NULL, *msg_in = NULL; - int f, r = 0; + int msg_out_len = 0, f, r = 0; mxml_node_t *b; - if (session->tree_out) + if (session->tree_out) { + + unsigned char *zmsg_out; msg_out = mxmlSaveAllocString(session->tree_out, whitespace_cb); + CWMP_LOG(DEBUG,"Message OUT \n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n%s\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>",msg_out); + if (cwmp->conf.compression != COMP_NONE) { + if (zlib_compress(msg_out, &zmsg_out, &msg_out_len, cwmp->conf.compression)) { + return -1; + } + FREE(msg_out); + msg_out = (char *) zmsg_out; + } else { + msg_out_len = strlen(msg_out); + } + } while (1) { f = 0; - if (http_send_message(cwmp, msg_out, &msg_in)) + if (http_send_message(cwmp, msg_out, msg_out_len,&msg_in)) { goto error; + } if (msg_in) { + CWMP_LOG(DEBUG,"Message IN \n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n%s\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",msg_in); if (s = strstr(msg_in, "")) sscanf(s, "%d",&f); if (f) {