diff --git a/antd-config.ini b/antd-config.ini index 4dbd6b9..0de4146 100644 --- a/antd-config.ini +++ b/antd-config.ini @@ -13,6 +13,10 @@ database=/opt/www/database/ htdocs=/opt/www/htdocs ; tmp dir tmpdir=/opt/www/tmp/ +; server log +server_log = /var/log/antd.log +; server error log +error_log = /var/log/antd_error.log ; server backlocg backlog=5000 ; eable or disalbe SSL diff --git a/configure.ac b/configure.ac index 30136ab..e467166 100644 --- a/configure.ac +++ b/configure.ac @@ -96,4 +96,4 @@ AM_CONDITIONAL([OSX], [test "$build_mac" = "yes"]) AC_CONFIG_FILES([Makefile]) # output the script: -AC_OUTPUT \ No newline at end of file +AC_OUTPUT diff --git a/dist/antd-1.0.4b.tar.gz b/dist/antd-1.0.4b.tar.gz index 3acb0b9..e2c5931 100644 Binary files a/dist/antd-1.0.4b.tar.gz and b/dist/antd-1.0.4b.tar.gz differ diff --git a/http_server.c b/http_server.c index acd9815..ba2b8a4 100644 --- a/http_server.c +++ b/http_server.c @@ -6,6 +6,50 @@ config_t *config() return &server_config; } +void error_log(const char* fmt, ...) +{ + if(server_config.errorfp) + { + va_list arguments; + char * data; + va_start( arguments, fmt); + int dlen = vsnprintf(0,0,fmt,arguments) + 1; + va_end(arguments); + if ((data = (char*)malloc(dlen*sizeof(char))) != 0) + { + va_start(arguments, fmt); + vsnprintf(data, dlen, fmt, arguments); + va_end(arguments); + fwrite(data,dlen,1,server_config.errorfp); + fflush(server_config.errorfp); + free(data); + } + } +} + +#ifdef DEBUG +void server_log(const char* fmt, ...) +{ + + if(server_config.logfp) + { + va_list arguments; + char * data; + va_start( arguments, fmt); + int dlen = vsnprintf(0,0,fmt,arguments) + 1; + va_end(arguments); + if ((data = (char*)malloc(dlen*sizeof(char))) != 0) + { + va_start(arguments, fmt); + vsnprintf(data, dlen, fmt, arguments); + va_end(arguments); + fwrite(data,dlen,1,server_config.logfp); + fflush(server_config.logfp); + free(data); + } + } +} +#endif void destroy_config() { list_free(&(server_config.rules)); @@ -20,8 +64,17 @@ void destroy_config() free(server_config.htdocs); if (server_config.tmpdir) free(server_config.tmpdir); - - LOG("Unclosed connection: %d\n", server_config.connection); + if(server_config.errorfp) + { + fclose(server_config.errorfp); + } +#ifdef DEBUG + if(server_config.logfp) + { + fclose(server_config.logfp); + } +#endif + LOG("Unclosed connection: %d", server_config.connection); } static int config_handler(void *conf, const char *section, const char *name, @@ -65,6 +118,16 @@ static int config_handler(void *conf, const char *section, const char *name, { pconfig->n_workers = atoi(value); } + else if (MATCH("SERVER", "error_log")) + { + pconfig->errorfp = fopen(value, "w"); + } +#ifdef DEBUG + else if (MATCH("SERVER", "server_log")) + { + pconfig->logfp = fopen(value, "w"); + } +#endif #ifdef USE_OPENSSL else if (MATCH("SERVER", "ssl.enable")) { @@ -137,15 +200,15 @@ void load_config(const char *file) #endif if (ini_parse(file, config_handler, &server_config) < 0) { - LOG("Can't load '%s'\n. Used defaut configuration", file); + ERROR("Can't load '%s'. Used defaut configuration", file); } else { - LOG("Using configuration : %s\n", file); + LOG("Using configuration : %s", file); #ifdef USE_OPENSSL - LOG("SSL enable %d\n", server_config.usessl); - LOG("SSL cert %s\n", server_config.sslcert); - LOG("SSL key %s\n", server_config.sslkey); + LOG("SSL enable %d", server_config.usessl); + LOG("SSL cert %s", server_config.sslcert); + LOG("SSL key %s", server_config.sslkey); #endif } init_file_system(); @@ -219,7 +282,7 @@ void *accept_request(void *data) task->handle = accept_request; return task; default: - LOG("Error performing SSL handshake %d %d %lu\n", stat, ret, ERR_get_error()); + ERROR("Error performing SSL handshake %d %d %lu", stat, ret, ERR_get_error()); //server_config.connection++; ERR_print_errors_fp(stderr); unknow(rq->client); @@ -248,7 +311,7 @@ void *accept_request(void *data) } } #endif - LOG("Ready for reading %d\n", client->sock); + //LOG("Ready for reading %d\n", client->sock); //server_config.connection++; read_buf(rq->client, buf, sizeof(buf)); line = buf; @@ -256,7 +319,7 @@ void *accept_request(void *data) token = strsep(&line, " "); if (!line) { - LOG("No method found\n"); + LOG("No method found"); unknow(rq->client); return task; } @@ -267,7 +330,7 @@ void *accept_request(void *data) token = strsep(&line, " "); if (!line) { - LOG("No request found\n"); + LOG("No request found"); unknow(rq->client); return task; } @@ -299,7 +362,7 @@ void *resolve_request(void *data) char *oldrqp = NULL; strcpy(path, server_config.htdocs); strcat(path, url); - LOG("Path is : %s \n", path); + LOG("Path is : %s", path); //if (path[strlen(path) - 1] == '/') // strcat(path, "index.html"); if (stat(path, &st) == -1) @@ -369,7 +432,7 @@ void *resolve_request(void *data) if (h) { //sprintf(path,"/%s%s",h,url); - LOG("WARNING::::Access octetstream via handle %s\n", h); + LOG("WARNING::::Access octetstream via handle %s", h); //if(execute_plugin(client,buf,method,rq) < 0) // cannot_execute(client); free(task); @@ -391,7 +454,7 @@ void *finish_request(void *data) { destroy_request(data); server_config.connection--; - LOG("Remaining connection %d\n", server_config.connection); + LOG("Remaining connection %d", server_config.connection); return NULL; } @@ -526,7 +589,7 @@ int startup(unsigned *port) error_die("getsockname"); *port = ntohs(name.sin_port); } - LOG("back log is %d\n", server_config.backlog); + LOG("back log is %d", server_config.backlog); if (listen(httpd, server_config.backlog) < 0) error_die("listen"); return (httpd); @@ -614,9 +677,9 @@ void *decode_request_header(void *data) //if(line) free(line); memset(buf, 0, sizeof(buf)); strcat(buf, url); - LOG("Original query: %s\n", url); + LOG("Original query: %s", url); query = apply_rules(host, buf); - LOG("Processed query: %s\n", query); + LOG("Processed query: %s", query); dput(rq->request, "RESOURCE_PATH", url_decode(buf)); if (query) { @@ -699,7 +762,7 @@ void *decode_post_request(void *data) return task; if (ctype == NULL || clen == -1) { - LOG("Bad request\n"); + LOG("Bad request"); badrequest(rq->client); return task; } @@ -767,7 +830,7 @@ void ws_confirm_request(void *client, const char *key) sprintf(buf, "\r\n"); antd_send(client, buf, strlen(buf)); - LOG("%s\n", "Websocket is now enabled for plugin"); + LOG("%s", "Websocket is now enabled for plugin"); } /** * Decode the cookie header to a dictionary @@ -948,7 +1011,8 @@ void *decode_multi_part_request_data(void *data) fseek(fp, 0, SEEK_SET); //fseek(fp,-2, SEEK_CUR); totalsize -= 2; - ftruncate(fileno(fp), totalsize); + int stat = ftruncate(fileno(fp), totalsize); + UNUSED(stat); fclose(fp); line = strdup(buf); @@ -967,7 +1031,7 @@ void *decode_multi_part_request_data(void *data) } else { - LOG("Cannot write file to :%s\n", file_path); + ERROR("Cannot write file to :%s", file_path); } free(file_path); free(part_file); @@ -978,7 +1042,7 @@ void *decode_multi_part_request_data(void *data) // check if end of request if (line && strstr(line, boundend)) { - LOG("End request %s\n", boundend); + LOG("End request %s", boundend); free(line); free(boundend); return task; @@ -1082,7 +1146,7 @@ void *execute_plugin(void *data, const char *pname) antd_request_t *rq = (antd_request_t *)data; antd_task_t *task = antd_create_task(NULL, (void *)rq, NULL, rq->client->last_io); task->priority++; - LOG("Plugin name '%s'\n", pname); + LOG("Plugin name '%s'", pname); //load the plugin if ((plugin = plugin_lookup((char *)pname)) == NULL) @@ -1106,7 +1170,7 @@ void *execute_plugin(void *data, const char *pname) fn = (void *(*)(void *))dlsym(plugin->handle, PLUGIN_HANDLER); if ((error = dlerror()) != NULL) { - LOG("Problem when finding %s method from %s : %s \n", PLUGIN_HANDLER, pname, error); + ERROR("Problem when finding %s method from %s : %s", PLUGIN_HANDLER, pname, error); unknow(rq->client); return task; } diff --git a/httpd.c b/httpd.c index 61ad655..e348759 100644 --- a/httpd.c +++ b/httpd.c @@ -3,14 +3,16 @@ #include "http_server.h" #include "lib/ini.h" -// define the cipher suit used -// dirty hack, this should be configured by the configuration file -#define CIPHER_SUIT "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256" - static antd_scheduler_t scheduler; static int server_sock = -1; #ifdef USE_OPENSSL + +// define the cipher suit used +// dirty hack, this should be configured by the configuration file +#define CIPHER_SUIT "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256" + + static int ssl_session_ctx_id = 1; SSL_CTX *ctx; void init_openssl() @@ -33,7 +35,7 @@ SSL_CTX *create_context() ctx = SSL_CTX_new(method); if (!ctx) { - perror("Unable to create SSL context"); + ERROR("Unable to create SSL context"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } @@ -75,7 +77,7 @@ void configure_context(SSL_CTX *ctx) exit(EXIT_FAILURE); } if (!SSL_CTX_check_private_key(ctx)) { - LOG("Failed to validate cert \n"); + ERROR("Failed to validate cert"); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } @@ -95,7 +97,6 @@ void stop_serve(int dummy) { sigprocmask(SIG_BLOCK, &mask, NULL); antd_scheduler_destroy(&scheduler); unload_all_plugin(); - destroy_config(); #ifdef USE_OPENSSL FIPS_mode_set(0); SSL_CTX_free(ctx); @@ -110,6 +111,7 @@ void stop_serve(int dummy) { #endif if(server_sock != -1) close(server_sock); + destroy_config(); sigprocmask(SIG_UNBLOCK, &mask, NULL); } @@ -142,7 +144,7 @@ int main(int argc, char* argv[]) #endif server_sock = startup(&port); - LOG("httpd running on port %d\n", port); + LOG("httpd running on port %d", port); // default to 4 workers antd_scheduler_init(&scheduler, config()->n_workers); scheduler.validate_data = 1; @@ -155,7 +157,7 @@ int main(int argc, char* argv[]) pthread_t scheduler_th; if (pthread_create(&scheduler_th, NULL,(void *(*)(void *))antd_wait, (void*)&scheduler) != 0) { - perror("pthread_create: cannot create worker\n"); + ERROR("pthread_create: cannot create worker"); stop_serve(0); exit(1); } @@ -185,7 +187,7 @@ int main(int argc, char* argv[]) { client_ip = inet_ntoa(client_name.sin_addr); client->ip = strdup(client_ip); - LOG("Client IP: %s\n", client_ip); + LOG("Client IP: %s", client_ip); //LOG("socket: %d\n", client_sock); } diff --git a/lib/dbhelper.c b/lib/dbhelper.c index 5cf2a8b..420a183 100644 --- a/lib/dbhelper.c +++ b/lib/dbhelper.c @@ -5,7 +5,7 @@ sqlite3 * database(const char* file) sqlite3* db; int rc = sqlite3_open(file,&db); if (rc != SQLITE_OK) { - LOG( "Cannot open database: %s %s\n",file, sqlite3_errmsg(db)); + ERROR( "Cannot open database: %s %s",file, sqlite3_errmsg(db)); sqlite3_close(db); return NULL; } @@ -23,7 +23,7 @@ int dbquery(sqlite3* db,const char* sql, int (*call_back)()) sqlite3_mutex_leave(sqlite3_db_mutex(db)); if(rc != SQLITE_OK) { - LOG("Cannot query : '%s' [%s]\n", sql,err_msg); + ERROR("Cannot query : '%s' [%s]", sql,err_msg); sqlite3_free(err_msg); return 0; } diff --git a/lib/handle.c b/lib/handle.c index a9a9778..aaa5d63 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -111,7 +111,7 @@ int antd_send(void *src, const void* data, int len) case SSL_ERROR_ZERO_RETURN: { // peer disconnected... - //printf("SSL_ERROR_ZERO_RETURN \n"); + ERROR("SSLWRITE: SSL_ERROR_ZERO_RETURN: peer disconected: %d", source->sock); break; } @@ -132,6 +132,7 @@ int antd_send(void *src, const void* data, int len) //source->attempt++; continue; // more data to read... } + ERROR("SSL WRITE: want read but select error on the socket %d: %s", source->sock, strerror(errno)); break; } @@ -152,12 +153,14 @@ int antd_send(void *src, const void* data, int len) //source->attempt++; continue; // can write more data now... } + ERROR("SSL WRITE: want write but select error on the socket %d: %s", source->sock, strerror(errno)); break; } default: { - // other error + // other error + ERROR("SSLWRITE: Unknown error on %d: %s", source->sock, ERR_get_error()); break; } } @@ -238,7 +241,7 @@ int antd_recv(void *src, void* data, int len) case SSL_ERROR_ZERO_RETURN: { // peer disconnected... - //printf("SSL_ERROR_ZERO_RETURN \n"); + ERROR("SSL READ: SSL_ERROR_ZERO_RETURN, peer disconnected %d", source->sock); break; } @@ -259,6 +262,7 @@ int antd_recv(void *src, void* data, int len) //source->attempt++; continue; // more data to read... } + ERROR("SSL READ: want read but select error on the socket %d: %s", source->sock, strerror(errno)); break; } @@ -279,12 +283,14 @@ int antd_recv(void *src, void* data, int len) //source->attempt++; continue; // can write more data now... } + ERROR("SSL READ: want write but select error on the socket %d: %s", source->sock, strerror(errno)); break; } default: { // other error + ERROR("SSL READ: unkown error on %d: %s", source->sock, ERR_get_error()); break; } } @@ -479,13 +485,12 @@ int __b(void* client, const unsigned char* data, int size) } int __f(void* client, const char* file) { - printf("Open file %s\n",file ); unsigned char buffer[BUFFLEN]; FILE *ptr; ptr = fopen(file,"rb"); if(!ptr) { - LOG("Cannot read : %s\n", file); + LOG("Cannot read : %s", file); return 0; } size_t size; @@ -642,8 +647,8 @@ void destroy_request(void *data) { if (!data) return; - LOG("Close request\n"); antd_request_t *rq = (antd_request_t *)data; + LOG("Close request %d", rq->client->sock); // free all other thing if (rq->request) { diff --git a/lib/handle.h b/lib/handle.h index f491a37..4617ffd 100644 --- a/lib/handle.h +++ b/lib/handle.h @@ -31,6 +31,10 @@ #ifdef USE_OPENSSL int __attribute__((weak)) usessl(); #endif +void __attribute__((weak)) error_log(const char*, ...); +#ifdef DEBUG +void __attribute__((weak)) server_log(const char*, ...); +#endif //extern config_t server_config; typedef struct{ int sock; @@ -61,6 +65,10 @@ typedef struct { int maxcon; int connection; int n_workers; + FILE* errorfp; +#ifdef DEBUG + FILE* logfp; +#endif #ifdef USE_OPENSSL int usessl; char* sslcert; diff --git a/lib/scheduler.c b/lib/scheduler.c index bb499a9..7b541ae 100644 --- a/lib/scheduler.c +++ b/lib/scheduler.c @@ -160,13 +160,13 @@ void antd_scheduler_init(antd_scheduler_t* scheduler, int n) scheduler->scheduler_sem = sem_open("scheduler", O_CREAT, 0600, 0); if (scheduler->scheduler_sem == SEM_FAILED) { - LOG("Cannot open semaphore for scheduler\n"); + ERROR("Cannot open semaphore for scheduler"); exit(-1); } scheduler->worker_sem = sem_open("worker", O_CREAT, 0600, 0); if (!scheduler->worker_sem) { - LOG("Cannot open semaphore for workers\n"); + ERROR("Cannot open semaphore for workers"); exit(-1); } // init lock @@ -180,7 +180,7 @@ void antd_scheduler_init(antd_scheduler_t* scheduler, int n) scheduler->workers = (antd_worker_t*)malloc(n*(sizeof(antd_worker_t))); if(!scheduler->workers) { - LOG("Cannot allocate memory for worker\n"); + ERROR("Cannot allocate memory for worker"); exit(-1); } for(int i = 0; i < scheduler->n_workers;i++) @@ -197,7 +197,7 @@ void antd_scheduler_init(antd_scheduler_t* scheduler, int n) } } } - LOG("Antd scheduler initialized with %d worker\n", scheduler->n_workers); + LOG("Antd scheduler initialized with %d worker", scheduler->n_workers); } /* destroy all pending task @@ -207,7 +207,7 @@ void antd_scheduler_destroy(antd_scheduler_t* scheduler) { // free all the chains stop(scheduler); - LOG("Destroy remaining queue\n"); + LOG("Destroy remaining queue"); for(int i=0; i < N_PRIORITY; i++) { destroy_queue(scheduler->task_queue[i]); @@ -324,7 +324,7 @@ int antd_task_schedule(antd_scheduler_t* scheduler) if(scheduler->validate_data && difftime( time(NULL), it->task->access_time) > MAX_VALIDITY_INTERVAL) { // data task is not valid - LOG("Task data is not valid \n"); + LOG("Task data is not valid, task will be killed"); if(scheduler->destroy_data) scheduler->destroy_data(it->task->data); if(it->task->callback) diff --git a/lib/utils.c b/lib/utils.c index cd88bf4..c60ea54 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -191,7 +191,9 @@ char* mime(const char* file) if(!ex) return "application/octet-stream"; mime_t m = mime_from_ext(ex); if(ex) + { free(ex); + } return (char*)m.type; } @@ -200,7 +202,9 @@ int is_bin(const char* file) char * ex = ext(file); mime_t m = mime_from_ext(ex); if(ex) + { free(ex); + } return m.bin; } @@ -228,9 +232,9 @@ int regex_match(const char* expr,const char* search, int msize, regmatch_t* matc /* Compile regular expression */ reti = regcomp(®ex, expr, REG_ICASE | REG_EXTENDED); if( reti ){ - LOG("Could not compile regex: %s\n",expr); + //ERROR("Could not compile regex: %s",expr); regerror(reti, ®ex, msgbuf, sizeof(msgbuf)); - LOG("Regex match failed: %s\n", msgbuf); + //ERROR("Regex match failed: %s", msgbuf); return 0; } @@ -246,7 +250,7 @@ int regex_match(const char* expr,const char* search, int msize, regmatch_t* matc } else{ regerror(reti, ®ex, msgbuf, sizeof(msgbuf)); - LOG("Regex match failed: %s\n", msgbuf); + //ERROR("Regex match failed: %s\n", msgbuf); ret = 0; } @@ -256,7 +260,9 @@ int regex_match(const char* expr,const char* search, int msize, regmatch_t* matc } char *url_decode(const char *str) { if(!str) + { return NULL; + } char *pstr = (char*)str, *buf = malloc(strlen(str) + 1), *pbuf = buf; while (*pstr) { @@ -468,4 +474,4 @@ void sha1(const char* text, char* out) SHA1_Update(&context, text, strlen(text)); SHA1_Final(d, &context); digest_to_hex(d,out); -} \ No newline at end of file +} diff --git a/lib/utils.h b/lib/utils.h index 60cd3d4..ee57e30 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -54,11 +54,13 @@ THE SOFTWARE. #define true 1 #define false 0 #ifdef DEBUG - #define LOG(a,...) printf("%s:%d: " a, __FILE__, \ + #define LOG(a,...) server_log("%s:%d: " a "\n", __FILE__, \ __LINE__, ##__VA_ARGS__) #else #define LOG(a,...) do{}while(0) #endif +#define ERROR(a,...) error_log("%s:%d: " a "\n", __FILE__, \ + __LINE__, ##__VA_ARGS__) // add this to the utils #define UNUSED(x) (void)(x) diff --git a/plugin_manager.c b/plugin_manager.c index fcb30bc..4b17f7d 100644 --- a/plugin_manager.c +++ b/plugin_manager.c @@ -45,7 +45,7 @@ struct plugin_entry *plugin_load(char *name) plugin_table[hashval] = np; } else /* already there */ { - LOG("The plugin %s id already loaded\n", name); + LOG("The plugin %s id already loaded", name); } return np; @@ -64,7 +64,7 @@ void * plugin_from_file(char* name) lib_handle = dlopen(path, RTLD_NOW| RTLD_GLOBAL); if (!lib_handle) { - LOG("Cannot load plugin '%s' : '%s'\n",name,dlerror()); + ERROR("Cannot load plugin '%s' : '%s'",name,dlerror()); if(path) free(path); return NULL; @@ -72,7 +72,7 @@ void * plugin_from_file(char* name) // set database path fn = (void (*)(const char *, config_t*))dlsym(lib_handle, "__init_plugin__"); if ((error = dlerror()) != NULL) - LOG("Problem when setting data path for %s : %s \n", name,error); + ERROR("Problem when finding plugin init function for %s : %s", name,error); else (*fn)(name,config()); if(path) @@ -88,7 +88,7 @@ void unload_plugin(struct plugin_entry* np) fn = (void(*)()) dlsym(np->handle, "__release__"); if ((error = dlerror()) != NULL) { - LOG("Cant not release plugin %s : %s \n", np->pname,error); + ERROR("Cant not release plugin %s : %s", np->pname,error); } if(fn) { @@ -103,7 +103,6 @@ void unload_plugin(struct plugin_entry* np) */ void unload_plugin_by_name(const char* name) { - LOG("%s\n","Unloading thing"); struct plugin_entry *np; int hasval = hash(name, HASHSIZE); np = plugin_table[hasval]; @@ -114,9 +113,13 @@ void unload_plugin_by_name(const char* name) } else { - for (; np != NULL; np = np->next) + for (np ; np != NULL; np = np->next) + { if (np->next != NULL && strcmp(name, np->next->pname) == 0) + { break; + } + } if(np == NULL) return; // the plugin is is not loaded unload_plugin(np->next); np->next = np->next->next; @@ -127,7 +130,7 @@ void unload_plugin_by_name(const char* name) */ void unload_all_plugin() { - LOG("Unload all plugins\n"); + LOG("Unload all plugins"); for(int i=0;i