コード例 #1
0
/*
    bind socket with port for server socket
*/
int bind_socket( int *socket_ptr, int port)
{
	struct sockaddr_in serv_addr;
	
	int ret = 0;

	//printf("port = %d\n", port );
	//printf("socket_ptr = %d\n", socket_ptr );
	*socket_ptr = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if ( *socket_ptr < 0 ) {
        fprintf(stdout,"create socket failed\n");
        return -1;
    }

	set_socket_reusable(*socket_ptr);
	set_TCP_keepalive(*socket_ptr);
	set_TCP_NODELAY ( *socket_ptr );
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
	serv_addr.sin_port = htons ( port );
	

	ret = bind( *socket_ptr, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr_in));
	if ( ret  < 0 ) {
		fprintf(stdout,"bind socket error\n");
		return -1;
	}
	return 0;
}
コード例 #2
0
/*
 *  TCP Connections Establishment function
 */
int connect_to ( int *fd , char *ip , int port ) 
{
	struct sockaddr_in peer_addr;
	int ret = 0;

	*fd =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if ( *fd < 0 ) {
		fprintf(stdout," socket creation failed\n");
		return -1;
	}

	set_socket_send_timeout( *fd, 3);
	set_socket_reusable(*fd);
	//set_TCP_keepalive(*fd);
	set_TCP_NODELAY ( *fd );

	peer_addr.sin_family = AF_INET;
	peer_addr.sin_addr.s_addr = inet_addr(ip);
	peer_addr.sin_port = htons(port);
	
	fprintf(stdout," connect to %s:%d\n",  ip, port);
	ret = connect( *fd, (struct sockaddr*) &peer_addr, sizeof( peer_addr ) ); 
	if ( ret < 0 ) 
	{
		fprintf(stdout,"  connect() failed\n");
		close_socket( fd );
		return -1;
	}
	return 0;
}
コード例 #3
0
ファイル: main.cpp プロジェクト: olafurw/sammy
int main(int argc, char *argv[])
{
    auto log = std::unique_ptr<sammy::log>(new sammy::log());
    log->info("Starting server.");

    unsigned int request_id = 1;

    addrinfo* res = create_addrinfo();
    int sockfd = create_socket(res);
    
    set_socket_reusable(sockfd);
    set_socket_bind(sockfd, res);
    set_socket_non_blocking(sockfd);
    set_socket_listen(sockfd);
    
    int efd = create_epoll();

    set_epoll_interface(efd, sockfd);
    
    // Init the domain config loading
    auto domain_storage = std::make_shared<sammy::domain_storage>();
    if(domain_storage->errors())
    {
        log->error("Error loading config.");
        exit(1);
    }

    // Init cache
    auto cache = std::make_shared<sammy::cache_storage>();

    // Init events
    epoll_event* events = new epoll_event[MAX_EPOLL_EVENTS];

    sammy::thread::pool thread_pool;
    
    std::map<int, std::string> client_ip_address;

    log->info("Server started");

    while( true )
    {
        const int event_count = epoll_wait(efd, events, MAX_EPOLL_EVENTS, -1);

        for(int i = 0; i < event_count; ++i)
        {
            const epoll_event& event = events[i];
            
            if( (event.events & EPOLLERR) ||
                (event.events & EPOLLHUP) ||
                (!(event.events & EPOLLIN)))
            {
                std::cout << "Error in the file descriptor." << std::endl;
                close(event.data.fd);
                continue;
            }
            else if(sockfd == event.data.fd)
            {
                while( true )
                {
                    sockaddr_in cli_addr;
                    socklen_t clilen{ sizeof(cli_addr) };

                    // Accept the the request
                    int newsockfd = accept(sockfd, (sockaddr*)&cli_addr, &clilen);
                    if(newsockfd == -1)
                    {
                        break;
                    }

                    set_socket_non_blocking(sockfd);
                    set_epoll_interface(efd, newsockfd);
                    
                    std::string out;
                    inet_ntop(AF_INET, &(cli_addr.sin_addr), &out[0], INET_ADDRSTRLEN);
                    client_ip_address[newsockfd] = out;
                }
                
                continue;
            }
            else
            {
                int newsockfd = event.data.fd;
                
                std::string client_address = client_ip_address[newsockfd];
                
                std::string request_str = "";
                size_t read_result = 0;
                read_request(newsockfd, read_result, request_str);

                // If the read result isn't ok
                if(read_result == -1)
                {
                    log->error("Error in read result, error #" + std::to_string(errno));
                    close(newsockfd);
                    continue;
                }

                // The request string is empty
                if(request_str.empty())
                {
                    log->error("Request string empty.");
                    close(newsockfd);
                    continue;
                }

                // Parse request string
                auto client_request = std::make_shared<sammy::request>(request_id, request_str);
                if(client_request->errors())
                {
                    log->error("Request parse error: " + client_request->error_text());
                    close(newsockfd);
                    continue;
                }

                request_id++;
                
                // Load domain configuration
                std::string response = "";
                auto domain = domain_storage->get_domain(client_request->get_host());

                // If this server does not serve the domain being asked for, we close the connection.
                if(!domain)
                {
                    log->error(client_address + " : " + client_request->get_host() + " : " + client_request->get_method() + " : " + client_request->get_path() + " : Domain not served.");
                    close(newsockfd);
                    continue;
                }

                // If the client address is blacklisted, we close the connection.
                if(domain->is_blacklisted(client_address))
                {
                    log->error(client_address + " : " + client_request->get_host() + " : " + client_request->get_method() + " : " + client_request->get_path() + " : IP blacklisted.");
                    close(newsockfd);
                    continue;
                }

                // Add the task, to be processed by the thread pool when possible
                thread_pool.add_task(std::make_shared<sammy::thread::task>(newsockfd, domain, client_request, cache, client_address));
                
                continue;
            }
        }
    }

    delete [] events;

    return 0;
}