#6030: fix the connection request error when binding an used port

Signed-off-by: Anis Ellouze <anis.ellouze@pivasoftware.com>
This commit is contained in:
Anis Ellouze 2015-01-23 17:32:06 +01:00 committed by MOHAMED Kallel
parent c8b1af0ea8
commit 6e26929e87
8 changed files with 117 additions and 40 deletions

View file

@ -142,6 +142,21 @@ void bkp_session_simple_insert(char *parent, char *child, char *value)
pthread_mutex_unlock (&mutex_backup_session);
}
void bkp_session_simple_insert_in_parent(char *parent, char *child, char *value)
{
mxml_node_t *n, *b = bkp_tree;
pthread_mutex_lock (&mutex_backup_session);
n = mxmlFindElement(b, b, parent, NULL, NULL, MXML_DESCEND);
if(!n)
n = bkp_session_insert(bkp_tree, parent,NULL);
b = mxmlFindElement(n, n, child, NULL, NULL, MXML_DESCEND);
if(b)
mxmlDelete(b);
bkp_session_insert(n,child,value);
pthread_mutex_unlock (&mutex_backup_session);
}
void bkp_session_move_inform_to_inform_send ()
{
mxml_node_t *b = bkp_tree;
@ -751,6 +766,14 @@ int cwmp_load_saved_session(struct cwmp *cwmp, char **ret, enum backup_loading l
break;
}
}
if(load == CR_PORT)
{
if(b->type == MXML_ELEMENT && strcmp(b->value.element.name, "connection_request") == 0)
{
*ret = load_child_value(b, "port");
break;
}
}
if(load == ALL)
{
if(b->type == MXML_ELEMENT && strcmp(b->value.element.name, "queue_event") == 0)

19
cwmp.c
View file

@ -505,9 +505,9 @@ void *thread_uloop_run (void *v)
return NULL;
}
void *thread_http_cr_server_init (void *v)
void *thread_http_cr_server_listen (void *v)
{
http_server_init();
http_server_listen();
return NULL;
}
@ -546,6 +546,13 @@ int main(int argc, char **argv)
return error;
}
http_server_init();
error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_listen, NULL);
if (error<0)
{
CWMP_LOG(ERROR,"Error when creating the http connection request server thread!");
}
error = pthread_create(&ubus_thread, NULL, &thread_uloop_run, NULL);
if (error<0)
{
@ -566,12 +573,8 @@ int main(int argc, char **argv)
{
CWMP_LOG(ERROR,"Error when creating the download thread!");
}
error = pthread_create(&http_cr_server_thread, NULL, &thread_http_cr_server_init, NULL);
if (error<0)
{
CWMP_LOG(ERROR,"Error when creating the http connection request server thread!");
}
cwmp_schedule_session (cwmp);
cwmp_schedule_session(cwmp);
pthread_join(ubus_thread, NULL);
pthread_join(periodic_event_thread, NULL);
pthread_join(scheduleInform_thread, NULL);

38
event.c
View file

@ -463,7 +463,7 @@ void connection_request_ip_value_change(struct cwmp *cwmp)
if(bip == NULL)
{
bkp_session_simple_insert("connection_request", "ip", cwmp->conf.ip);
bkp_session_simple_insert_in_parent("connection_request", "ip", cwmp->conf.ip);
bkp_session_save();
return;
}
@ -473,12 +473,12 @@ void connection_request_ip_value_change(struct cwmp *cwmp)
event_container = cwmp_add_event_container (cwmp, EVENT_IDX_4VALUE_CHANGE, "");
if (event_container == NULL)
{
FREE(bip);
FREE(bip);
pthread_mutex_unlock (&(cwmp->mutex_session_queue));
return;
}
cwmp_save_event_container (cwmp,event_container);
bkp_session_simple_insert("connection_request", "ip", cwmp->conf.ip);
bkp_session_simple_insert_in_parent("connection_request", "ip", cwmp->conf.ip);
bkp_session_save();
pthread_mutex_unlock (&(cwmp->mutex_session_queue));
pthread_cond_signal(&(cwmp->threshold_session_send));
@ -486,6 +486,38 @@ void connection_request_ip_value_change(struct cwmp *cwmp)
FREE(bip);
}
void connection_request_port_value_change(struct cwmp *cwmp, int port)
{
char *bport = NULL;
struct event_container *event_container;
int error;
char bufport[32];
sprintf(bufport, "%d", port);
error = cwmp_load_saved_session(cwmp, &bport, CR_PORT);
if(bport == NULL)
{
bkp_session_simple_insert_in_parent("connection_request", "port", bufport);
bkp_session_save();
return;
}
if (strcmp(bport, bufport)!=0)
{
event_container = cwmp_add_event_container (cwmp, EVENT_IDX_4VALUE_CHANGE, "");
if (event_container == NULL)
{
FREE(bport);
return;
}
cwmp_save_event_container (cwmp,event_container);
bkp_session_simple_insert_in_parent("connection_request", "port", bufport);
bkp_session_save();
}
FREE(bport);
}
int cwmp_root_cause_events (struct cwmp *cwmp)
{
int error;

69
http.c
View file

@ -43,6 +43,7 @@
#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
static struct http_client http_c;
static int cr_socket_desc;
#ifdef HTTP_CURL
static CURL *curl;
@ -338,53 +339,67 @@ http_done:
void http_server_init(void)
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
static int cr_request = 0;
static time_t restrict_start_time = 0;
time_t current_time;
bool service_available;
struct sockaddr_in server;
int cr_port;
for(;;) {
cr_port = cwmp_main.conf.connection_request_port;
int i = (DEFAULT_CONNECTION_REQUEST_PORT == cr_port)? 1 : 0;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
cr_socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (cr_socket_desc == -1)
{
CWMP_LOG (ERROR,"Could not open server socket for Connection Requests");
CWMP_LOG (ERROR,"Could not open server socket for Connection Requests, Error no is : %d, Error description is : %s", errno, strerror(errno));
sleep(1);
continue;
}
/* enable SO_REUSEADDR */
int reusaddr = 1;
if (setsockopt(cr_socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
CWMP_LOG (WARNING,"setsockopt(SO_REUSEADDR) failed");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(cwmp_main.conf.connection_request_port);
/* enable SO_REUSEADDR */
int reusaddr = 1;
if (setsockopt(socket_desc, SOL_SOCKET, SO_REUSEADDR, &reusaddr, sizeof(int)) < 0) {
CWMP_LOG (WARNING,"setsockopt(SO_REUSEADDR) failed");
}
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
CWMP_LOG (ERROR,"Could not bind server socket, Error no is : %d, Error description is : %s", errno, strerror(errno));
sleep(1);
continue;
for(;;i++) {
server.sin_port = htons(cr_port);
//Bind
if( bind(cr_socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
CWMP_LOG (ERROR,"Could not bind server socket on the port %d, Error no is : %d, Error description is : %s", cr_port, errno, strerror(errno));
cr_port = DEFAULT_CONNECTION_REQUEST_PORT + i;
CWMP_LOG (INFO,"Trying to use another connection request port: %d", cr_port);
continue;
}
break;
}
break;
}
char buf[64];
sprintf(buf,UCI_CPE_PORT_PATH"=%d", cr_port);
uci_set_state_value(buf);
connection_request_port_value_change(&cwmp_main, cr_port);
CWMP_LOG (INFO,"Connection Request server initiated with the port: %d", cr_port);
}
CWMP_LOG (INFO,"Connection Request server initiated");
void http_server_listen(void)
{
int client_sock , c , *new_sock;
static int cr_request = 0;
static time_t restrict_start_time = 0;
time_t current_time;
bool service_available;
struct sockaddr_in client;
//Listen
listen(socket_desc , 3);
listen(cr_socket_desc , 3);
//Accept and incoming connection
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
while( (client_sock = accept(cr_socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
current_time = time(NULL);
service_available = true;

View file

@ -30,7 +30,8 @@
typedef enum backup_loading {
ALL,
ACS,
CR_IP
CR_IP,
CR_PORT
} backup_loading;
struct search_keywords {

View file

@ -228,5 +228,7 @@ int netlink_init(void);
char * mix_get_time(void);
char * mix_get_time_of(time_t t_time);
void *thread_exit_program (void *v);
void connection_request_ip_value_change(struct cwmp *cwmp);
void connection_request_port_value_change(struct cwmp *cwmp, int port);
#endif /* _CWMP_H__ */

View file

@ -50,6 +50,7 @@ void http_client_exit(void);
int http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in);
void http_server_init(void);
void http_server_listen(void);
#endif

View file

@ -14,7 +14,7 @@ if [ -z "$default_management_server_connection_request_url" ]; then
local tmp_json=${FLAGS_json}
FLAGS_json=${FLAGS_FALSE}
local ip=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q -P /var/state get cwmp.cpe.ip`
local port=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q get cwmp.cpe.port`
local port=`/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q -P /var/state get cwmp.cpe.port`
FLAGS_value=$tmp_value
FLAGS_json=$tmp_json