Пример #1
0
static void handle_incoming_request(struct st_h2o_http1_conn_t *conn)
{
    size_t inreqlen = conn->sock->input->size < H2O_MAX_REQLEN ? conn->sock->input->size : H2O_MAX_REQLEN;
    int reqlen, minor_version;
    struct phr_header headers[H2O_MAX_HEADERS];
    size_t num_headers = H2O_MAX_HEADERS;
    ssize_t entity_body_header_index;
    h2o_iovec_t expect;

    /* need to set request_begin_at here for keep-alive connection */
    if (conn->req.timestamps.request_begin_at.tv_sec == 0)
        conn->req.timestamps.request_begin_at = *h2o_get_timestamp(conn->super.ctx, NULL, NULL);

    reqlen = phr_parse_request(conn->sock->input->bytes, inreqlen, (const char **)&conn->req.input.method.base,
                               &conn->req.input.method.len, (const char **)&conn->req.input.path.base, &conn->req.input.path.len,
                               &minor_version, headers, &num_headers, conn->_prevreqlen);
    conn->_prevreqlen = inreqlen;

    switch (reqlen) {
    default: // parse complete
        conn->_reqsize = reqlen;
        if ((entity_body_header_index = fixup_request(conn, headers, num_headers, minor_version, &expect)) != -1) {
            conn->req.timestamps.request_body_begin_at = *h2o_get_timestamp(conn->super.ctx, NULL, NULL);
            if (expect.base != NULL) {
                if (!h2o_lcstris(expect.base, expect.len, H2O_STRLIT("100-continue"))) {
                    set_timeout(conn, NULL, NULL);
                    h2o_socket_read_stop(conn->sock);
                    h2o_send_error_417(&conn->req, "Expectation Failed", "unknown expectation",
                                       H2O_SEND_ERROR_HTTP1_CLOSE_CONNECTION);
                    return;
                }
                static const h2o_iovec_t res = {H2O_STRLIT("HTTP/1.1 100 Continue\r\n\r\n")};
                h2o_socket_write(conn->sock, (void *)&res, 1, on_continue_sent);
            }
            if (create_entity_reader(conn, headers + entity_body_header_index) != 0) {
                return;
            }
            if (expect.base != NULL) {
                /* processing of the incoming entity is postponed until the 100 response is sent */
                h2o_socket_read_stop(conn->sock);
                return;
            }
            conn->_req_entity_reader->handle_incoming_entity(conn);
        } else {
            set_timeout(conn, NULL, NULL);
            h2o_socket_read_stop(conn->sock);
            process_request(conn);
        }
        return;
    case -2: // incomplete
        if (inreqlen == H2O_MAX_REQLEN) {
            send_bad_request(conn);
        }
        return;
    case -1: // error
        /* upgrade to HTTP/2 if the request starts with: PRI * HTTP/2 */
        if (conn->super.ctx->globalconf->http1.upgrade_to_http2) {
            /* should check up to the first octet that phr_parse_request returns an error */
            static const h2o_iovec_t HTTP2_SIG = {H2O_STRLIT("PRI * HTTP/2")};
            if (conn->sock->input->size >= HTTP2_SIG.len && memcmp(conn->sock->input->bytes, HTTP2_SIG.base, HTTP2_SIG.len) == 0) {
                h2o_accept_ctx_t accept_ctx = {conn->super.ctx, conn->super.hosts};
                h2o_socket_t *sock = conn->sock;
                struct timeval connected_at = conn->super.connected_at;
                /* destruct the connection after detatching the socket */
                conn->sock = NULL;
                close_connection(conn, 1);
                /* and accept as http2 connection */
                h2o_http2_accept(&accept_ctx, sock, connected_at);
                return;
            }
        }
        if (inreqlen <= 4 && contains_crlf_only(conn->sock->input->bytes, inreqlen)) {
            close_connection(conn, 1);
        } else {
            send_bad_request(conn);
        }
        return;
    }
}
Пример #2
0
//--------------------------------------------------------------------------
void rpc_debmod_t::dbg_stopped_at_debug_event(void)
{
  qstring cmd = prepare_rpc_packet(RPC_STOPPED_AT_DEBUG_EVENT);

  qfree(process_request(cmd));
}
Пример #3
0
int thread_main(server_decl_t * srv)
{
     ci_connection_t con;
     char clientname[CI_MAXHOSTNAMELEN + 1];
     int ret, request_status = CI_NO_STATUS;
     int keepalive_reqs;
//***********************
     thread_signals(0);
//*************************
     srv->srv_id = getpid();    //Setting my pid ...

     for (;;) {
          /*
             If we must shutdown IMEDIATELLY it is time to leave the server
             else if we are going to shutdown GRACEFULLY we are going to die 
             only if there are not any accepted connections
           */
          if (child_data->to_be_killed == IMMEDIATELY) {
               srv->running = 0;
               return 1;
          }

          if ((ret = get_from_queue(con_queue, &con)) == 0) {
               if (child_data->to_be_killed) {
                    srv->running = 0;
                    return 1;
               }
               ret = wait_for_queue(con_queue);
               continue;
          }

          if (ret < 0) {        //An error has occured
               ci_debug_printf(1,
                               "Fatal Error!!! Error getting a connection from connections queue!!!\n");
               break;
          }

          ci_thread_mutex_lock(&counters_mtx);  /*Update counters as soon as possible */
          (child_data->freeservers)--;
          (child_data->usedservers)++;
          ci_thread_mutex_unlock(&counters_mtx);

          ci_netio_init(con.fd);
          ret = 1;
          if (srv->current_req == NULL)
               srv->current_req = newrequest(&con);
          else
               ret = recycle_request(srv->current_req, &con);

          if (srv->current_req == NULL || ret == 0) {
               ci_sockaddr_t_to_host(&(con.claddr), clientname,
                                     CI_MAXHOSTNAMELEN);
               ci_debug_printf(1, "Request from %s denied...\n", clientname);
               hard_close_connection((&con));
               goto end_of_main_loop_thread;    /*The request rejected. Log an error and continue ... */
          }

          keepalive_reqs = 0;
          do {
               if (MAX_KEEPALIVE_REQUESTS > 0
                   && keepalive_reqs >= MAX_KEEPALIVE_REQUESTS)
                    srv->current_req->keepalive = 0;    /*do not keep alive connection */
               if (child_data->to_be_killed)    /*We are going to die do not keep-alive */
                    srv->current_req->keepalive = 0;

               if ((request_status = process_request(srv->current_req)) == CI_NO_STATUS) {
                    ci_debug_printf(5,
                                    "Process request timeout or interrupted....\n");
                    ci_request_reset(srv->current_req);
                    break;
               }
               srv->served_requests++;
               srv->served_requests_no_reallocation++;
               keepalive_reqs++;

               /*Increase served requests. I dont like this. The delay is small but I don't like... */
               ci_thread_mutex_lock(&counters_mtx);
               (child_data->requests)++;
               ci_thread_mutex_unlock(&counters_mtx);

               log_access(srv->current_req, request_status);
//             break; //No keep-alive ......

               if (child_data->to_be_killed  == IMMEDIATELY)
                    break;      //Just exiting the keep-alive loop

               /*if we are going to term gracefully we will try to keep our promice for
                 keepalived request....
                */
               if (child_data->to_be_killed  == GRACEFULLY && 
                   srv->current_req->keepalive == 0)
                    break;

               ci_debug_printf(8, "Keep-alive:%d\n",
                               srv->current_req->keepalive);
               if (srv->current_req->keepalive && keepalive_request(srv->current_req)) {
                   ci_debug_printf(8,
                                   "Server %d going to serve new request from client (keep-alive) \n",
                                   srv->srv_id);
               }
               else
                    break;
          } while (1);

          if (srv->current_req) {
               if (request_status != CI_OK || child_data->to_be_killed) {
                    hard_close_connection(srv->current_req->connection);
               }
               else {
                    close_connection(srv->current_req->connection);
               }
          }
          if (srv->served_requests_no_reallocation >
              MAX_REQUESTS_BEFORE_REALLOCATE_MEM) {
               ci_debug_printf(5,
                               "Max requests reached, reallocate memory and buffers .....\n");
               ci_request_destroy(srv->current_req);
               srv->current_req = NULL;
               srv->served_requests_no_reallocation = 0;
          }


        end_of_main_loop_thread:
          ci_thread_mutex_lock(&counters_mtx);
          (child_data->freeservers)++;
          (child_data->usedservers)--;
          ci_thread_mutex_unlock(&counters_mtx);
          ci_thread_cond_signal(&free_server_cond);

     }
     srv->running = 0;
     return 0;
}
Пример #4
0
static int scan_request(struct connection *cn)
{
	char *s;
	int c, state;

	s = cn->header_input.middle;
	state = cn->header_input.state;
	while (state != 8 && s < cn->header_input.end) {
		c = *s++;
		if (c == 0) {
			log_d("read_connection: NUL in headers");
			close_connection(cn);
			return -1;
		}
		switch (state) {
		case 0:
			switch (c) {
			default:
				state = 1;
				break;
			case '\r':
			case '\n':
				break;
			case ' ':
			case '\t':
				state = 2;
				break;
			}
			if (state) {
				gettimeofday(&cn->itv, 0);
				set_connection_state(cn, HC_READING);
			}
			break;
		case 1:
			switch (c) {
			default:
				break;
			case ' ':
			case '\t':
				state = 2;
				break;
			case '\r':
				state = 3;
				break;
			case '\n':
				state = 8;
				break;
			}
			break;
		case 2:
			switch (c) {
			case 'H':
				state = 4;
				break;
			default:
				state = 1;
				break;
			case ' ':
			case '\t':
				break;
			case '\r':
				state = 3;
				break;
			case '\n':
				state = 8;
				break;
			}
			break;
		case 3:
			switch (c) {
			case '\n':
				state = 8;
				break;
			default:
				state = 1;
				break;
			case ' ':
			case '\t':
				state = 2;
				break;
			case '\r':
				break;
			}
			break;
		case 4:
			switch (c) {
			case '\r':
				state = 5;
				break;
			case '\n':
				state = 6;
				break;
			}
			break;
		case 5:
			switch (c) {
			default:
				state = 4;
			case '\r':
				break;
			case '\n':
				state = 6;
				break;
			}
			break;
		case 6:
			switch (c) {
			case '\r':
				state = 7;
				break;
			case '\n':
				state = 8;
				break;
			default:
				state = 4;
				break;
			}
			break;
		case 7:
			switch (c) {
			default:
				state = 4;
			case '\r':
				break;
			case '\n':
				state = 8;
				break;
			}
			break;
		}
	}
	cn->header_input.state = state;
	cn->header_input.middle = s;
	if (state == 8) {
		if (process_request(cn->r) == -1) {
			switch (cn->connection_state) {
			case HC_FORKED:
				return 0;
			default:
				close_connection(cn);
			case HC_FREE:
				return -1;
			}
		}
		if (begin_response(cn) == -1) {
			close_connection(cn);
			return -1;
		}
		set_connection_state(cn, HC_WRITING);
	}
	return 0;
}
Пример #5
0
//--------------------------------------------------------------------------
void rpc_debmod_t::dbg_term(void)
{
  qstring cmd = prepare_rpc_packet(RPC_TERM);

  qfree(process_request(cmd));
}
Пример #6
0
//Handles the authentication request
static int handle_authentication_request(ap_filter_t* f, apr_bucket_brigade* bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) {
    request_rec* r = f->r;
    process_request(r);
}
Пример #7
0
void *
server_thread (void *arg)
{
    int rc;
    int interactive = (arg != NULL);
    socklen_t len;
    int request_len;
    client_t client;
    char remote_ip[16];
    char request[REQUESTLEN + 1];
    llist_entry *le;
    datum_t rootdatum;

    for (;;)
    {
        client.valid = 0;
        len = sizeof(client.addr);

        if (interactive)
        {
            pthread_mutex_lock(&server_interactive_mutex);
            SYS_CALL( client.fd, accept(interactive_socket->sockfd, (struct sockaddr *) &(client.addr), &len));
            pthread_mutex_unlock(&server_interactive_mutex);
        }
        else
        {
            pthread_mutex_lock  ( &server_socket_mutex );
            SYS_CALL( client.fd, accept(server_socket->sockfd, (struct sockaddr *) &(client.addr), &len));
            pthread_mutex_unlock( &server_socket_mutex );
        }
        if ( client.fd < 0 )
        {
            err_ret("server_thread() error");
            debug_msg("server_thread() %lx clientfd = %d errno=%d\n",
                      (unsigned long) pthread_self(), client.fd, errno);
            continue;
        }

        my_inet_ntop( AF_INET, (void *)&(client.addr.sin_addr), remote_ip, 16 );

        if ( !strcmp(remote_ip, "127.0.0.1")
                || gmetad_config.all_trusted
                || (llist_search(&(gmetad_config.trusted_hosts), (void *)remote_ip, strcmp, &le) == 0) )
        {
            client.valid = 1;
        }

        if(! client.valid )
        {
            debug_msg("server_thread() %s tried to connect and is not a trusted host",
                      remote_ip);
            close( client.fd );
            continue;
        }

        client.filter=0;
        client.http=0;
        gettimeofday(&client.now, NULL);

        if (interactive)
        {
            request_len = readline(client.fd, request, REQUESTLEN);
            if (request_len < 0)
            {
                err_msg("server_thread() could not read request from %s", remote_ip);
                close(client.fd);
                continue;
            }
            debug_msg("server_thread() received request \"%s\" from %s", request, remote_ip);

            rc = process_request(&client, request);
            if (rc == 1)
            {
                err_msg("Got a malformed path request from %s", remote_ip);
                close(client.fd);
                continue;
            }
            else if (rc == 2)
            {
                debug_msg("Got a STAT request from %s", remote_ip);
                close(client.fd);
                continue;
            }
        }
        else
            strcpy(request, "/");

        if(root_report_start(&client))
        {
            err_msg("server_thread() %lx unable to write root preamble (DTD, etc)",
                    (unsigned long) pthread_self() );
            close(client.fd);
            continue;
        }

        /* Start search at the root node. */
        rootdatum.data = &root;
        rootdatum.size = sizeof(root);

        if (process_path(&client, request, &rootdatum, NULL))
        {
            err_msg("server_thread() %lx unable to write XML tree info",
                    (unsigned long) pthread_self() );
            close(client.fd);
            continue;
        }

        if(root_report_end(&client))
        {
            err_msg("server_thread() %lx unable to write root epilog",
                    (unsigned long) pthread_self() );
        }

        close(client.fd);
    }
}
Пример #8
0
void Casan::loop ()
{
    Msg in (l2_) ;
    Msg out (l2_) ;
    l2net::l2_recv_t ret ;
    uint8_t oldstatus ;
    long int hlid ;
    l2addr *srcaddr ;
    int mtu ;				// mtu announced by master in assoc msg

    oldstatus = status_ ;		// keep old value for debug display
    sync_time (curtime) ;		// get current time
    retrans_.loop (*l2_, curtime) ;	// check needed retransmissions

    srcaddr = NULL ;

    ret = in.recv () ;			// get received message
    if (ret == l2net::RECV_OK)
	srcaddr = l2_->get_src () ;	// get a new address

    switch (status_)
    {
	case SL_COLDSTART :
	    send_discover (out) ;
	    twait_.init (curtime) ;
	    status_ = SL_WAITING_UNKNOWN ;
	    break ;

	case SL_WAITING_UNKNOWN :
	    if (ret == l2net::RECV_OK)
	    {
		retrans_.check_msg_received (in) ;

		if (is_ctl_msg (in))
		{
		    if (is_hello (in, hlid))
		    {
			DBGLN1 (F ("Received a CTL HELLO msg")) ;
			change_master (hlid, -1) ;	// don't change mtu
			twait_.init (curtime) ;
			status_ = SL_WAITING_KNOWN ;
		    }
		    else if (is_assoc (in, sttl_, mtu))
		    {
			DBGLN1 (F ("Received a CTL ASSOC msg")) ;
			change_master (-1, mtu) ;	// "unknown" hlid
			send_assoc_answer (in, out) ;
			trenew_.init (curtime, sttl_) ;
			status_ = SL_RUNNING ;
		    }
		    else DBGLN1 (F (RED ("Unkwnon CTL"))) ;
		}
	    }

	    if (status_ == SL_WAITING_UNKNOWN && twait_.next (curtime))
		send_discover (out) ;

	    break ;

	case SL_WAITING_KNOWN :
	    if (ret == l2net::RECV_OK)
	    {
		retrans_.check_msg_received (in) ;

		if (is_ctl_msg (in))
		{
		    if (is_hello (in, hlid))
		    {
			DBGLN1 (F ("Received a CTL HELLO msg")) ;
			change_master (hlid, -1) ;	// don't change mtu
		    }
		    else if (is_assoc (in, sttl_, mtu))
		    {
			DBGLN1 (F ("Received a CTL ASSOC msg")) ;
			change_master (-1, mtu) ;	// unknown hlid
			send_assoc_answer (in, out) ;
			trenew_.init (curtime, sttl_) ;
			status_ = SL_RUNNING ;
		    }
		    else DBGLN1 (F (RED ("Unkwnon CTL"))) ;
		}
	    }

	    if (status_ == SL_WAITING_KNOWN)
	    {
		if (twait_.expired (curtime))
		{
		    reset_master () ;		// master_ is no longer known
		    send_discover (out) ;
		    twait_.init (curtime) ;	// reset timer
		    status_ = SL_WAITING_UNKNOWN ;
		}
		else if (twait_.next (curtime))
		{
		    send_discover (out) ;
		}
	    }

	    break ;

	case SL_RUNNING :
	case SL_RENEW :
	    if (ret == l2net::RECV_OK)
	    {
		retrans_.check_msg_received (in) ;

		if (is_ctl_msg (in))
		{
		    if (is_hello (in, hlid))
		    {
			DBGLN1 (F ("Received a CTL HELLO msg")) ;
			if (! same_master (srcaddr) || hlid != hlid_)
			{
			    int oldhlid = hlid_ ;

			    change_master (hlid, 0) ;	// reset mtu
			    if (oldhlid != -1)
			    {
				twait_.init (curtime) ;
				status_ = SL_WAITING_KNOWN ;
			    }
			}
		    }
		    else if (is_assoc (in, sttl_, mtu))
		    {
			DBGLN1 (F ("Received a CTL ASSOC msg")) ;
			if (same_master (srcaddr))
			{
			    negociate_mtu (mtu) ;
			    send_assoc_answer (in, out) ;
			    trenew_.init (curtime, sttl_) ;
			    status_ = SL_RUNNING ;
			}
		    }
		    else DBGLN1 (F (RED ("Unkwnon CTL"))) ;
		}
		else		// request for a normal resource
		{
		    // deduplicate () ;
		    process_request (in, out) ;
		    out.send (*master_) ;
		}
	    }
	    else if (ret == l2net::RECV_TRUNCATED)
	    {
		DBGLN1 (F (RED ("Request too large"))) ;
		out.set_type (COAP_TYPE_ACK) ;
		out.set_id (in.get_id ()) ;
		out.set_token (in.get_token ()) ;
		option o (option::MO_Size1, l2_->mtu ()) ;
		out.push_option (o) ;
		out.set_code (COAP_CODE_TOO_LARGE) ;
		out.send (*master_) ;
	    }

	    check_observed_resources (out) ;

	    if (status_ == SL_RUNNING && trenew_.renew (curtime))
	    {
		send_discover (out) ;
		status_ = SL_RENEW ;
	    }

	    if (status_ == SL_RENEW && trenew_.next (curtime))
	    {
		send_discover (out) ;
	    }

	    if (status_ == SL_RENEW && trenew_.expired (curtime))
	    {
		reset_master () ;	// master_ is no longer known
		send_discover (out) ;
		twait_.init (curtime) ;	// reset timer
		status_ = SL_WAITING_UNKNOWN ;
	    }

	    break ;

	default :
	    DBGLN1 (F ("Error : casan status not known")) ;
	    DBGLN1 (status_) ;
	    break ;
    }

    if (oldstatus != status_)
    {
	DBG1 (F ("Status: " C_GREEN)) ;
	print_status (oldstatus) ;
	DBG1 (F (C_RESET " -> " C_GREEN)) ;
	print_status (status_) ;
	DBGLN1 (F (C_RESET)) ;
    }

    if (srcaddr != NULL)
	delete srcaddr ;
}
void *synchronization_responding_main(void *arg)
{
	BIO     *bio_acc    = NULL;
	BIO     *bio_client = NULL;
    	SSL     *ssl_client = NULL;
    	SSL_CTX *ctx        = NULL;

	int     err;
	char    *host[1];

    	ctx = setup_server_ctx(UA_CERTFILE_PATH, UA_CERTFILE_PASSWD, PHR_ROOT_CA_ONLY_CERT_CERTFILE_PATH);
    	bio_acc = BIO_new_accept(UA_SYNCHRONIZATION_RESPONDING_PORT);
    	if(!bio_acc)
        	int_error("Creating server socket failed");
  
    	if(BIO_do_accept(bio_acc) <= 0)
        	int_error("Binding server socket failed");
  
    	for(;;)
    	{
        	if(BIO_do_accept(bio_acc) <= 0)
            		int_error("Accepting connection failed");
 
        	bio_client = BIO_pop(bio_acc);

        	if(!(ssl_client = SSL_new(ctx)))
            		int_error("Creating SSL context failed");

        	SSL_set_bio(ssl_client, bio_client, bio_client);
		if(SSL_accept(ssl_client) <= 0)
		{
        		fprintf(stderr, "Accepting SSL connection failed\n");
			goto ERROR_AT_SSL_LAYER;
		}

		host[0] = USER_AUTH_CN; 
    		if((err = post_connection_check(ssl_client, host, 1, false, NULL)) != X509_V_OK)
    		{
        		fprintf(stderr, "Checking peer certificate failed\n\"%s\"\n", X509_verify_cert_error_string(err));
        		goto ERROR_AT_SSL_LAYER;
    		}

		// Process the request
		if(!process_request(ssl_client))
			goto ERROR_AT_SSL_LAYER;

ERROR_AT_SSL_LAYER:

		SSL_cleanup(ssl_client);
		ssl_client = NULL;
    		ERR_remove_state(0);
    	}
    
    	SSL_CTX_free(ctx);
	ctx = NULL;

    	BIO_free(bio_acc);
	bio_acc = NULL;

	pthread_exit(NULL);
    	return NULL;
}
Пример #10
0
int main(int argc, char *argv[])
{
	SOAP_SOCKET m;
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
	pthread_t tid;
	pthread_mutex_init(&global_flag, NULL);
	pthread_mutex_init(&libssh2_flag, NULL);
	pthread_cond_init(&termination_flag, NULL);
#endif
	struct soap soap, *tsoap = NULL;
	psoap = &soap;

	int ch, msglevel = LOG_INFO;
	static char *USAGE = "\nUSAGE:\noph_server [-d] [-l <log_file>] [-p <port>] [-v] [-w]\n";

	fprintf(stdout, "%s", OPH_VERSION);
	fprintf(stdout, "%s", OPH_DISCLAIMER);

	set_debug_level(msglevel + 10);

	while ((ch = getopt(argc, argv, "dhl:p:vwxz")) != -1) {
		switch (ch) {
			case 'd':
				msglevel = LOG_DEBUG;
				break;
			case 'h':
				fprintf(stdout, "%s", USAGE);
				return 0;
			case 'l':
				oph_log_file_name = optarg;
				break;
			case 'p':
				oph_server_port = optarg;
				break;
			case 'v':
				return 0;
				break;
			case 'w':
				if (msglevel < LOG_WARNING)
					msglevel = LOG_WARNING;
				break;
			case 'x':
				fprintf(stdout, "%s", OPH_WARRANTY);
				return 0;
			case 'z':
				fprintf(stdout, "%s", OPH_CONDITIONS);
				return 0;
			default:
				fprintf(stdout, "%s", USAGE);
				return 0;
		}
	}

	set_debug_level(msglevel + 10);
	pmesg(LOG_INFO, __FILE__, __LINE__, "Selected log level %d\n", msglevel);

#ifdef OPH_SERVER_LOCATION
	oph_server_location = strdup(OPH_SERVER_LOCATION);
#else
	oph_server_location = getenv(OPH_SERVER_LOCATION_STR);
	if (!oph_server_location) {
		fprintf(stderr, "OPH_SERVER_LOCATION has to be set\n");
		return 1;
	}
#endif
	pmesg(LOG_DEBUG, __FILE__, __LINE__, "Server location '%s'\n", oph_server_location);

	char configuration_file[OPH_MAX_STRING_SIZE];
	snprintf(configuration_file, OPH_MAX_STRING_SIZE, OPH_CONFIGURATION_FILE, oph_server_location);
	set_global_values(configuration_file);

	if (oph_log_file_name) {
		if (logfile)
			fclose(logfile);
		if (!(logfile = fopen(oph_log_file_name, "a"))) {
			fprintf(stderr, "Wrong log file name '%s'\n", oph_log_file_name);
			return 1;
		}
		pmesg(LOG_INFO, __FILE__, __LINE__, "Selected log file '%s'\n", oph_log_file_name);
		if (logfile)
			set_log_file(logfile);
	} else
		oph_log_file_name = hashtbl_get(oph_server_params, OPH_SERVER_CONF_LOGFILE);

	int int_port = strtol(oph_server_port, NULL, 10);

	if (oph_handle_signals()) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "A problem occurred while setting up signal dispositions\n");
		exit(1);
	}

	if (mysql_library_init(0, 0, 0)) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "Cannot setup MySQL\n");
		exit(1);
	}

	oph_tp_start_xml_parser();
	if (CRYPTO_thread_setup()) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "Cannot setup thread mutex for OpenSSL\n");
		exit(1);
	}
	soap_init(&soap);
	soap.fget = oph_http_get;
	if (soap_register_plugin(&soap, oph_plugin)) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "Cannot register %s plugin\n", OPH_PLUGIN_ID);
		soap_print_fault(&soap, stderr);
		cleanup();
		exit(-1);
	}
	// Register serverid
	struct oph_plugin_data *state = NULL;
	if (!(state = (struct oph_plugin_data *) soap_lookup_plugin(&soap, OPH_PLUGIN_ID))) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "Error on lookup plugin struct\n");
		soap_print_fault(&soap, stderr);
		cleanup();
		exit(-1);
	}
	state->serverid = strdup(oph_web_server);

#ifdef WITH_OPENSSL
	/* init gsoap context and SSL */
	if (soap_ssl_server_context(&soap, SOAP_TLSv1_2, oph_server_cert, oph_server_password, oph_server_ca, NULL, NULL, NULL, NULL)) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "SSL Server Context Error\n");
		soap_print_fault(&soap, stderr);
		cleanup();
		exit(1);
	}
#endif

	soap.accept_timeout = oph_server_inactivity_timeout;
	soap.send_timeout = soap.recv_timeout = oph_server_timeout;
	soap.bind_flags |= SO_REUSEADDR;
	m = soap_bind(&soap, NULL, int_port, 100);
	if (!soap_valid_socket(m)) {
		pmesg(LOG_ERROR, __FILE__, __LINE__, "Soap invalid socket\n");
		soap_print_fault(&soap, stderr);
		cleanup();
		exit(1);
	}
	pmesg(LOG_DEBUG, __FILE__, __LINE__, "Bind successful: socket = %d\n", m);

	for (;;) {
		SOAP_SOCKET s = soap_accept(&soap);
		if (!soap_valid_socket(s)) {
			if (soap.errnum) {
				pmesg(LOG_ERROR, __FILE__, __LINE__, "Soap invalid socket\n");
				soap_print_fault(&soap, stderr);
			} else
				pmesg(LOG_ERROR, __FILE__, __LINE__, "Server timed out (timeout set to %d seconds)\n", soap.accept_timeout);
			break;
		}
		tsoap = soap_copy(&soap);
		if (!tsoap) {
			soap_closesock(&soap);
			continue;
		}
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
		pthread_create(&tid, NULL, (void *(*)(void *)) &process_request, tsoap);
#else
		process_request(tsoap);
#endif
	}
	cleanup();
	return 0;
}