void init_fileAPI(void) { fileAPI.version = FILE_API_VERSION; fileAPI.is_file_service_enabled = &is_file_service_enabled; fileAPI.file_process = &file_process; fileAPI.get_file_name = &get_file_name; fileAPI.get_file_size = &get_file_size; fileAPI.get_file_processed_size = &get_file_processed_size; fileAPI.get_file_direction = &get_file_direction; fileAPI.get_sig_sha256 = &get_file_sig_sha256; fileAPI.set_file_name = &set_file_name; fileAPI.set_file_direction = &set_file_direction; fileAPI.set_file_policy_callback = &set_file_policy_callback; fileAPI.enable_file_type = &enable_file_type; fileAPI.enable_file_signature = &enable_file_signature; fileAPI.enable_file_capture = &enable_file_capture; fileAPI.set_file_action_log_callback = &set_file_action_log_callback; fileAPI.get_max_file_depth = &get_max_file_depth; fileAPI.set_log_buffers = &set_log_buffers; fileAPI.init_mime_mempool = &init_mime_mempool; fileAPI.init_log_mempool= &init_log_mempool; fileAPI.file_resume_block_add_file = &file_resume_block_add_file; fileAPI.file_resume_block_check = &file_resume_block_check; fileAPI.str_to_hash = &str_to_hash; fileAPI.file_signature_lookup = &file_signature_lookup; fileAPI.set_mime_decode_config_defauts = &set_mime_decode_config_defauts; fileAPI.set_mime_log_config_defauts = &set_mime_log_config_defauts; fileAPI.parse_mime_decode_args = &parse_mime_decode_args; fileAPI.process_mime_data = &process_mime_data; fileAPI.free_mime_session = &free_mime_session; fileAPI.is_decoding_enabled = &is_decoding_enabled; fileAPI.is_decoding_conf_changed = &is_decoding_conf_changed; fileAPI.check_decoding_conf = &check_decode_config; fileAPI.is_mime_log_enabled = &is_mime_log_enabled; fileAPI.finalize_mime_position = &finalize_mime_position; fileAPI.get_file_verdict = &get_file_verdict; fileAPI.render_block_verdict = &render_block_verdict; fileAPI.reserve_file = &file_capture_reserve; fileAPI.read_file = &file_capture_read; fileAPI.release_file = &file_capture_release; fileAPI.get_file_capture_size = &file_capture_size; fileAPI.get_file_type_id = &get_file_type_id; fileAPI.get_new_file_instance = &get_new_file_instance; fileAPI.create_file_context = &create_file_context; fileAPI.set_current_file_context = &set_current_file_context; fileAPI.get_current_file_context = &get_current_file_context; fileAPI.get_main_file_context = &get_main_file_context; fileAPI.process_file = &process_file_context; fileAPI.get_file_position = &get_file_position; fileAPI.reset_mime_paf_state = &reset_mime_paf_state; fileAPI.process_mime_paf_data = &process_mime_paf_data; fileAPI.check_data_end = check_data_end; fileAPI.check_paf_abort = &check_paf_abort; fileAPI.get_max_file_capture_size = get_max_file_capture_size; file_api = &fileAPI; init_mime(); }
/* return file descriptor if success, <0 otherwise */ int httpd_init(int sport, char *sname, int use_ssl, const char *certificate, const char *password, int use_v6) { struct addrinfo ask,*res = NULL; struct sockaddr_storage ss; int opt, rc, ss_len, v4 = 1, v6 = 0; char host[INET6_ADDRSTRLEN+1]; char serv[16]; char listen_port[6]; char *listen_ip = NULL; /* set config */ sprintf(listen_port, "%d", sport); server_name = sname; if (use_v6) { v6 = 1; } #ifdef USE_SSL with_ssl = use_ssl; #endif /* FIXME nthreads */ /* get server name */ gethostname(server_host,255); memset(&ask,0,sizeof(ask)); ask.ai_flags = AI_CANONNAME; if ((rc = getaddrinfo(server_host, NULL, &ask, &res)) == 0) { if (res->ai_canonname) { strcpy(server_host,res->ai_canonname); } if (res != NULL) { freeaddrinfo(res); res = NULL; } } /* bind to socket */ slisten = -1; memset(&ask, 0, sizeof(ask)); ask.ai_flags = AI_PASSIVE; if (listen_ip) { ask.ai_flags |= AI_CANONNAME; } ask.ai_socktype = SOCK_STREAM; /* try ipv6 first ... */ if (slisten == -1 && v6) { ask.ai_family = PF_INET6; g_timeout = 0; alarm(2); rc = getaddrinfo(listen_ip, listen_port, &ask, &res); if (g_timeout) { log_error_func(1, LOG_ERR,"getaddrinfo (ipv6): DNS timeout",NULL); } alarm(0); if (rc == 0) { if ((slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { log_error_func(1, LOG_ERR,"socket (ipv6)",NULL); } } else { log_error_func(1, LOG_ERR, "getaddrinfo (ipv6)", NULL); } } g_timeout = 0; alarm(2); /* ... failing that try ipv4 */ if (slisten == -1 && v4) { ask.ai_family = PF_INET; g_timeout = 0; alarm(1); rc = getaddrinfo(listen_ip, listen_port, &ask, &res); if (g_timeout) { log_error_func(1, LOG_ERR,"getaddrinfo (ipv4): DNS timeout",NULL); return -1; } alarm(0); if (rc == 0) { if ((slisten = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { log_error_func(1, LOG_ERR,"socket (ipv4)",NULL); return -1; } } else { log_error_func(1, LOG_ERR, "getaddrinfo (ipv4)", NULL); return -1; } } if (slisten == -1) { return -1; } memcpy(&ss,res->ai_addr,res->ai_addrlen); ss_len = res->ai_addrlen; if (res->ai_canonname) { strcpy(server_host,res->ai_canonname); } if ((rc = getnameinfo((struct sockaddr*)&ss,ss_len, host,INET6_ADDRSTRLEN,serv,15, NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { log_error_func(1, LOG_ERR, "getnameinfo", NULL); return -1; } tcp_port = atoi(serv); opt = 1; setsockopt(slisten,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); fcntl(slisten,F_SETFL,O_NONBLOCK); /* Use accept filtering, if available. */ #ifdef SO_ACCEPTFILTER { struct accept_filter_arg af; memset(&af,0,sizeof(af)); strcpy(af.af_name,"httpready"); setsockopt(slisten, SOL_SOCKET, SO_ACCEPTFILTER, (char*)&af, sizeof(af)); } #endif /* SO_ACCEPTFILTER */ if (bind(slisten, (struct sockaddr*) &ss, ss_len) == -1) { log_error_func(1, LOG_ERR,"bind",NULL); return -1; } if (listen(slisten, 2*max_conn) == -1) { log_error_func(1, LOG_ERR,"listen",NULL); return -1; } /* init misc stuff */ init_mime(mimetypes,"text/plain"); init_quote(); #ifdef USE_SSL if (with_ssl) { init_ssl(certificate, password); } #endif #ifdef DEBUG fprintf(stderr, "http server started\n" " ipv6 : %s\n" #ifdef USE_SSL " ssl : %s\n" #endif " node : %s\n" " ipaddr: %s\n" " port : %d\n" , res->ai_family == PF_INET6 ? "yes" : "no", #ifdef USE_SSL with_ssl ? "yes" : "no", #endif server_host,host,tcp_port); #endif if (res != NULL) { freeaddrinfo(res); } /* go! */ #ifdef HTTPD_USE_THREADS if (nthreads > 1) { int i; threads = malloc(sizeof(pthread_t) * nthreads); for (i = 1; i < nthreads; i++) { pthread_create(threads+i,NULL,mainloop,threads+i); pthread_detach(threads[i]); } } #endif return slisten; }