mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
#5432 fix the non responding connection request issue.
Signed-off-by: MOHAMED Kallel <mohamed.kallel@pivasoftware.com>
This commit is contained in:
parent
ee0df8c63c
commit
20a54a20cc
4 changed files with 160 additions and 162 deletions
13
cwmp.c
13
cwmp.c
|
|
@ -505,6 +505,12 @@ void *thread_uloop_run (void *v)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void *thread_http_cr_server_init (void *v)
|
||||
{
|
||||
http_server_init();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *thread_exit_program (void *v)
|
||||
{
|
||||
CWMP_LOG(INFO,"EXIT CWMP");
|
||||
|
|
@ -521,6 +527,7 @@ int main(int argc, char **argv)
|
|||
pthread_t scheduleInform_thread;
|
||||
pthread_t download_thread;
|
||||
pthread_t ubus_thread;
|
||||
pthread_t http_cr_server_thread;
|
||||
|
||||
if (error = cwmp_init(argc, argv, cwmp))
|
||||
{
|
||||
|
|
@ -559,11 +566,17 @@ 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);
|
||||
pthread_join(ubus_thread, NULL);
|
||||
pthread_join(periodic_event_thread, NULL);
|
||||
pthread_join(scheduleInform_thread, NULL);
|
||||
pthread_join(download_thread, NULL);
|
||||
pthread_join(http_cr_server_thread, NULL);
|
||||
|
||||
CWMP_LOG(INFO,"EXIT CWMP");
|
||||
return CWMP_OK;
|
||||
|
|
|
|||
291
http.c
291
http.c
|
|
@ -17,6 +17,9 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "cwmp.h"
|
||||
#include "log.h"
|
||||
|
||||
|
|
@ -40,7 +43,6 @@
|
|||
#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
|
||||
|
||||
static struct http_client http_c;
|
||||
static struct http_server http_s;
|
||||
|
||||
#ifdef HTTP_CURL
|
||||
static CURL *curl;
|
||||
|
|
@ -263,150 +265,151 @@ error:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
http_success_cr()
|
||||
{
|
||||
struct event_container *event_container;
|
||||
CWMP_LOG(INFO,"Connection Request thread: add connection request event in the queue");
|
||||
pthread_mutex_lock (&(cwmp_main.mutex_session_queue));
|
||||
event_container = cwmp_add_event_container (&cwmp_main, EVENT_IDX_6CONNECTION_REQUEST, "");
|
||||
pthread_mutex_unlock (&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
}
|
||||
|
||||
static void http_cr_new_client(int client, bool service_available)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[BUFSIZ];
|
||||
int8_t auth_status = 0;
|
||||
|
||||
fp = fdopen(client, "r+");
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
|
||||
char *username = cwmp_main.conf.cpe_userid;
|
||||
char *password = cwmp_main.conf.cpe_passwd;
|
||||
|
||||
if (!username || !password) {
|
||||
// if we dont have username or password configured proceed with connecting to ACS
|
||||
service_available = false;
|
||||
goto http_end;
|
||||
}
|
||||
|
||||
if (http_digest_auth_check("GET", "/", buffer + strlen("Authorization: Digest "), REALM, username, password, 300) == MHD_YES)
|
||||
auth_status = 1;
|
||||
else
|
||||
auth_status = 0;
|
||||
}
|
||||
|
||||
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
||||
/* end of http request (empty line) */
|
||||
goto http_end;
|
||||
}
|
||||
}
|
||||
if(!service_available) {
|
||||
goto http_end;
|
||||
}
|
||||
goto http_done;
|
||||
|
||||
http_end:
|
||||
if (!service_available) {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: Return 503 Service Unavailable");
|
||||
fputs("HTTP/1.1 503 Service Unavailable\r\n", fp);
|
||||
fputs("Connection: close\r\n", fp);
|
||||
fputs("Content-Length: 0\r\n", fp);
|
||||
} else if (auth_status) {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: success authentication");
|
||||
fputs("HTTP/1.1 200 OK\r\n", fp);
|
||||
fputs("Connection: close\r\n", fp);
|
||||
fputs("Content-Length: 0\r\n", fp);
|
||||
http_success_cr();
|
||||
} else {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: Return 401 Unauthorized");
|
||||
fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
|
||||
fputs("Connection: close\r\n", fp);
|
||||
http_digest_auth_fail_response(fp, "GET", "/", REALM, OPAQUE);
|
||||
fputs("\r\n", fp);
|
||||
}
|
||||
fputs("\r\n", fp);
|
||||
|
||||
http_done:
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void http_server_init(void)
|
||||
{
|
||||
char port[16];
|
||||
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;
|
||||
|
||||
sprintf(port,"%d",cwmp_main.conf.connection_request_port);
|
||||
http_s.http_event.cb = http_new_client;
|
||||
http_s.http_event.fd = usock(USOCK_TCP | USOCK_SERVER, "0.0.0.0", port);
|
||||
uloop_fd_add(&http_s.http_event, ULOOP_READ | ULOOP_EDGE_TRIGGER);
|
||||
}
|
||||
|
||||
static void http_new_client(struct uloop_fd *ufd, unsigned events)
|
||||
{
|
||||
int status;
|
||||
struct timeval t;
|
||||
static int cr_request = 0;
|
||||
static time_t restrict_start_time = 0;
|
||||
time_t current_time;
|
||||
bool service_available;
|
||||
|
||||
t.tv_sec = 60;
|
||||
t.tv_usec = 0;
|
||||
|
||||
for (;;) {
|
||||
int client = accept(ufd->fd, NULL, NULL);
|
||||
|
||||
/* set one minute timeout */
|
||||
if (setsockopt(ufd->fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&t, sizeof t)) {
|
||||
CWMP_LOG(ERROR,"setsockopt() failed");
|
||||
}
|
||||
|
||||
if (client == -1)
|
||||
break;
|
||||
|
||||
current_time = time(NULL);
|
||||
service_available = true;
|
||||
if ((restrict_start_time==0) ||
|
||||
((current_time-restrict_start_time) > CONNECTION_REQUEST_RESTRICT_PERIOD))
|
||||
{
|
||||
restrict_start_time = current_time;
|
||||
cr_request = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr_request++;
|
||||
if (cr_request>CONNECTION_REQUEST_RESTRICT_REQUEST)
|
||||
{
|
||||
restrict_start_time = current_time;
|
||||
service_available = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct uloop_process *uproc = calloc(1, sizeof(*uproc));
|
||||
if (!uproc || (uproc->pid = fork()) == -1) {
|
||||
free(uproc);
|
||||
close(client);
|
||||
}
|
||||
|
||||
if (uproc->pid != 0) {
|
||||
/* parent */
|
||||
/* register an event handler for when the child terminates */
|
||||
uproc->cb = http_del_client;
|
||||
uloop_process_add(uproc);
|
||||
close(client);
|
||||
} else {
|
||||
/* child */
|
||||
FILE *fp;
|
||||
char buffer[BUFSIZ];
|
||||
int8_t auth_status = 0;
|
||||
|
||||
fp = fdopen(client, "r+");
|
||||
|
||||
if(!service_available)
|
||||
goto http_end_child;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
|
||||
char *username = cwmp_main.conf.cpe_userid;
|
||||
char *password = cwmp_main.conf.cpe_passwd;
|
||||
|
||||
if (!username || !password) {
|
||||
// if we dont have username or password configured proceed with connecting to ACS
|
||||
service_available = false;
|
||||
goto http_end_child;
|
||||
}
|
||||
|
||||
if (http_digest_auth_check("GET", "/", buffer + strlen("Authorization: Digest "), REALM, username, password, 300) == MHD_YES)
|
||||
auth_status = 1;
|
||||
else
|
||||
auth_status = 0;
|
||||
}
|
||||
|
||||
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
||||
/* end of http request (empty line) */
|
||||
goto http_end_child;
|
||||
}
|
||||
|
||||
}
|
||||
error_child:
|
||||
/* here we are because of an error, e.g. timeout */
|
||||
status = ETIMEDOUT|ENOMEM;
|
||||
goto done_child;
|
||||
|
||||
http_end_child:
|
||||
fflush(fp);
|
||||
if (auth_status) {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: success authentication");
|
||||
status = 0;
|
||||
fputs("HTTP/1.1 200 OK\r\n", fp);
|
||||
fputs("Content-Length: 0\r\n", fp);
|
||||
} else if (!service_available) {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: Return 503 Service Unavailable");
|
||||
status = EACCES;
|
||||
fputs("HTTP/1.1 503 Service Unavailable\r\n", fp);
|
||||
fputs("Connection: close\r\n", fp);
|
||||
} else {
|
||||
CWMP_LOG (INFO,"Receive Connection Request: Return 401 Unauthorized");
|
||||
status = EACCES;
|
||||
fputs("HTTP/1.1 401 Unauthorized\r\n", fp);
|
||||
fputs("Connection: close\r\n", fp);
|
||||
http_digest_auth_fail_response(fp, "GET", "/", REALM, OPAQUE);
|
||||
fputs("\r\n", fp);
|
||||
}
|
||||
fputs("\r\n", fp);
|
||||
goto done_child;
|
||||
|
||||
done_child:
|
||||
fclose(fp);
|
||||
free(uproc);
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
http_del_client(struct uloop_process *uproc, int ret)
|
||||
{
|
||||
free(uproc);
|
||||
struct event_container *event_container;
|
||||
/* child terminated ; check return code */
|
||||
if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
|
||||
CWMP_LOG(INFO,"Connection Request thread: add connection request event in the queue");
|
||||
pthread_mutex_lock (&(cwmp_main.mutex_session_queue));
|
||||
event_container = cwmp_add_event_container (&cwmp_main, EVENT_IDX_6CONNECTION_REQUEST, "");
|
||||
pthread_mutex_unlock (&(cwmp_main.mutex_session_queue));
|
||||
pthread_cond_signal(&(cwmp_main.threshold_session_send));
|
||||
}
|
||||
for(;;) {
|
||||
//Create socket
|
||||
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
|
||||
if (socket_desc == -1)
|
||||
{
|
||||
CWMP_LOG (ERROR,"Could not open server socket for Connection Requests");
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
//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 for Connection Requests");
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
CWMP_LOG (INFO,"Connection Request server initiated");
|
||||
|
||||
//Listen
|
||||
listen(socket_desc , 3);
|
||||
|
||||
//Accept and incoming connection
|
||||
c = sizeof(struct sockaddr_in);
|
||||
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
|
||||
{
|
||||
current_time = time(NULL);
|
||||
service_available = true;
|
||||
if ((restrict_start_time==0) ||
|
||||
((current_time-restrict_start_time) > CONNECTION_REQUEST_RESTRICT_PERIOD))
|
||||
{
|
||||
restrict_start_time = current_time;
|
||||
cr_request = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr_request++;
|
||||
if (cr_request > CONNECTION_REQUEST_RESTRICT_REQUEST)
|
||||
{
|
||||
restrict_start_time = current_time;
|
||||
service_available = false;
|
||||
}
|
||||
}
|
||||
http_cr_new_client(client_sock, service_available);
|
||||
close(client_sock);
|
||||
}
|
||||
|
||||
if (client_sock < 0)
|
||||
{
|
||||
CWMP_LOG(ERROR,"Could not accept connections for Connection Requests!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,11 +41,6 @@ struct http_client
|
|||
char *url;
|
||||
};
|
||||
|
||||
struct http_server
|
||||
{
|
||||
struct uloop_fd http_event;
|
||||
};
|
||||
|
||||
#ifdef HTTP_CURL
|
||||
static size_t http_get_response(void *buffer, size_t size, size_t rxed, char **msg_in);
|
||||
#endif /* HTTP_CURL */
|
||||
|
|
@ -55,8 +50,6 @@ void http_client_exit(void);
|
|||
int http_send_message(struct cwmp *cwmp, char *msg_out, char **msg_in);
|
||||
|
||||
void http_server_init(void);
|
||||
static void http_new_client(struct uloop_fd *ufd, unsigned events);
|
||||
static void http_del_client(struct uloop_process *uproc, int ret);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
11
netlink.c
11
netlink.c
|
|
@ -34,17 +34,8 @@
|
|||
#include "log.h"
|
||||
|
||||
static void netlink_new_msg(struct uloop_fd *ufd, unsigned events);
|
||||
static void freecwmp_kickoff(struct uloop_timeout *);
|
||||
|
||||
static struct uloop_timeout netlink_timer = { .cb = freecwmp_kickoff };
|
||||
|
||||
static struct uloop_fd netlink_event = { .cb = netlink_new_msg };
|
||||
|
||||
static void freecwmp_kickoff(struct uloop_timeout *timeout)
|
||||
{
|
||||
http_server_init();
|
||||
}
|
||||
|
||||
static void freecwmp_netlink_interface(struct nlmsghdr *nlh)
|
||||
{
|
||||
struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA(nlh);
|
||||
|
|
@ -173,7 +164,5 @@ int netlink_init(void)
|
|||
struct uloop_fd dummy_event = { .fd = sock[1] };
|
||||
netlink_new_msg(&dummy_event, 0);
|
||||
|
||||
uloop_timeout_set(&netlink_timer, 2500);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue