static void receive_request(SOCKET sockfd)
{
	int bytes_recv;
	char buffer[BUFSIZ];
	char abuffer[64];
	int rc;

	rc = get_peer_address(sockfd, abuffer, 64);
	if (rc < 0) {
		ERR("get_peer_address");
		goto remove_connection;
	}

	bytes_recv = recv(sockfd, buffer, BUFSIZ, 0);
	if (bytes_recv < 0) {		/* error in communication */
		dlog(LOG_ERR, "Error in communication from %s\n", abuffer);
		goto remove_connection;
	}
	if (bytes_recv == 0) {		/* connection closed */
		dlog(LOG_INFO, "Connection closed from %s\n", abuffer);
		goto remove_connection;
	}

	dlog(LOG_INFO, "Received message from %s\n", abuffer);

	printf("--\n%s--\n", buffer);

	return;

remove_connection:
	/* close local socket */
	closesocket(sockfd);
	return;
}
Beispiel #2
0
static void
read_packet(connector_t connector) {
    packet_state_t rstate = &connector->rstate;

    int to_read;
    char *buffer;
    switch (rstate->state) {
        case READING_HEADER:
            to_read = rstate->total_header - rstate->processed_header;
            buffer = rstate->header;
        break;
        case READING_PAYLOAD:
            to_read = rstate->total_payload - rstate->processed_payload;
            buffer = rstate->buffer;
        break;
        default:
            assert(0);
    };

    int was_read = read(connector->fd, buffer, to_read);
    if (was_read <= 0 && errno != EWOULDBLOCK) {
        connector->state = ENDING;
        return;
    }

    switch (rstate->state) {
        case READING_HEADER:
            rstate->processed_header += was_read;
            if (rstate->processed_header == rstate->total_header) {
                rstate->state = READING_PAYLOAD;
                rstate->total_payload 
                    = ntohl(((packet_header_t)buffer)->payload_length);
                mlog(LOG_INFO, "read packet header from %X", 
                        get_peer_address(connector->fd));
            }
        break;
        case READING_PAYLOAD:
            rstate->processed_payload += was_read;
            if (rstate->processed_payload == rstate->total_payload) {
                connector->state = PRE_WRITING;
                mlog(LOG_INFO, "read whole packet from %X", 
                        get_peer_address(connector->fd));
            }
        break;
    };
}
Beispiel #3
0
static void
write_packet(connector_t connector) {
    packet_state_t wstate = &connector->wstate;

    int to_write;
    char *buffer;
    switch (wstate->state) {
        case WRITING_HEADER:
            to_write = wstate->total_header - wstate->processed_header;
            buffer = wstate->header;
        break;
        case WRITING_PAYLOAD:
            to_write = wstate->total_payload - wstate->processed_payload;
            buffer = wstate->buffer;
        break;
        default:
            assert(0);
    };

    int was_written = write(connector->fd, buffer, to_write);
    if (was_written <= 0 && errno != EWOULDBLOCK) {
        connector->state = ENDING;
        return;
    }

    switch (wstate->state) {
        case WRITING_HEADER:
            wstate->processed_header += was_written;
            if (wstate->processed_header == wstate->total_header) {
                wstate->state = WRITING_PAYLOAD;
                mlog(LOG_INFO, "wrote packet header to %X", 
                    get_peer_address(connector->fd));
            }
        break;
        case WRITING_PAYLOAD:
            wstate->processed_payload += was_written;
            if (wstate->processed_payload == wstate->total_payload) {
                connector->state = ENDING;
                mlog(LOG_INFO, "wrote whole packet to %X", 
                    get_peer_address(connector->fd));
            }
        break;
    };
}
Beispiel #4
0
static void
connector_handler(int fd, short event, void *arg) {
    connector_t connector = (connector_t)arg;
again:
    switch (connector->state) {
        case PRE_READING: {
            packet_state_t rstate = &connector->rstate;
            memset((void *)rstate, 0, sizeof(*rstate));
            rstate->state = READING_HEADER;
            rstate->total_header = sizeof(struct packet_header);
            connector->state = READING;
        }

        case READING:
            if (!(event & EV_READ)) { 
                break; 
            }
            read_packet(connector);
        break;

        case PRE_WRITING: {
            packet_state_t wstate = &connector->wstate;
            memset((void *)wstate, 0, sizeof(*wstate));
            wstate->state = WRITING_HEADER;
            wstate->total_header = sizeof(struct packet_header);
            memcpy(wstate->header, wstate->header, sizeof(sizeof(struct packet_header)));
            memcpy(wstate->buffer, wstate->buffer, wstate->total_payload);
            connector->state = WRITING;
        }

        case WRITING:
            if (!(event & EV_WRITE)) { 
                break; 
            }
            write_packet(connector);
        break;
            
        case ENDING:
            mlog(LOG_INFO, "terminating connection with %X", 
                get_peer_address(connector->fd));
            return;

        default:
            assert(0);
    };
    if (connector->state == ENDING)
        goto again;
    regenerate_connector_event(connector);
}
static void send_reply(SOCKET sockfd)
{
	int bytes_sent;
	char abuffer[64];
	int rc;
	char buffer[BUFSIZ] = "HTTP/1.1 200 OK\r\n"
		"Date: Sun, 08 May 2011 09:26:16 GMT\r\n"
		"Server: Apache/2.2.9\r\n"
		"Last-Modified: Mon, 02 Aug 2010 17:55:28 GMT\r\n"
		"Accept-Ranges: bytes\r\n"
		"Content-Length: 153\r\n"
		"Vary: Accept-Encoding\r\n"
		"Connection: close\r\n"
		"Content-Type: text/html\r\n"
		"\r\n"
		"<html><head><meta name=\"google-site-verification\" content=\"gTsIxyV43HSJraRPl6X1A5jzGFgQ3N__hKAcuL2QsO8\" /></head>"
		"<body><h1>It works!</h1></body></html>\r\n";

	rc = get_peer_address(sockfd, abuffer, 64);
	if (rc < 0) {
		ERR("get_peer_address");
		goto remove_connection;
	}

	bytes_sent = send(sockfd, buffer, strlen(buffer), 0);
	if (bytes_sent < 0) {		/* error in communication */
		dlog(LOG_ERR, "Error in communication to %s\n", abuffer);
		goto remove_connection;
	}
	if (bytes_sent == 0) {		/* connection closed */
		dlog(LOG_INFO, "Connection closed to %s\n", abuffer);
		goto remove_connection;
	}

	dlog(LOG_INFO, "Sent message to %s (bytes: %ld)\n", abuffer, bytes_sent);

	printf("--\n%s\n--\n", buffer);

	/* Close HTTP connection. */
	closesocket(sockfd);
	return;

remove_connection:
	/* close local socket */
	closesocket(sockfd);
	return;
}
Beispiel #6
0
static void handle_new_connection(OVERLAPPED *ovp)
{
	struct connection *conn;
	char abuffer[64];
	HANDLE hRet;
	int rc;

	rc = setsockopt(
			ac.sockfd,
			SOL_SOCKET,
			SO_UPDATE_ACCEPT_CONTEXT,
			(char *) &listenfd,
			sizeof(listenfd)
		  );
	DIE(rc < 0, "setsockopt");

	rc = get_peer_address(ac.sockfd, abuffer, 64);
	if (rc < 0) {
		ERR("get_peer_address");
		return;
	}

	dlog(LOG_DEBUG, "Accepted connection from %s\n", abuffer);

	/* Instantiate new connection handler. */
	conn = connection_create(ac.sockfd);

	/* Add socket to IoCompletionPort. */
	hRet = w_iocp_add_key(iocp, (HANDLE) conn->sockfd, (ULONG_PTR) conn);
	DIE(hRet != iocp, "w_iocp_add_key");

	/* Schedule receive operation. */
	connection_schedule_socket_receive(conn);

	/* Use AcceptEx to schedule new connection acceptance. */
	create_iocp_accept();

}
Beispiel #7
0
static void 
acceptor_handler(int fd, short event, void *arg) {
    acceptor_t acceptor = (acceptor_t)arg;
    int peer_fd = accept(acceptor->fd, NULL, NULL);
    if (peer_fd < 0) {
        return;
    }
    mlog(LOG_INFO, "got connection from %X", get_peer_address(peer_fd));
    connector_t connector = (connector_t)malloc(sizeof(struct connector));
    memset((void *)connector, 0, sizeof(struct connector));
    set_nonblockable(peer_fd);
    connector->fd = peer_fd;
    connector->state = PRE_READING;
    if (acceptor->head) {
        connector->next = acceptor->head;
        acceptor->head = connector;
    } else {
        acceptor->head = connector;
    }
    event_set(&connector->event, connector->fd, 
        EV_READ | EV_WRITE, connector_handler, (void *)connector);
    regenerate_connector_event(connector);
}
Beispiel #8
0
/*
 * Initialize state struct to default/empty values
 */
void init_state(state *st)
{
	static const char *filetypes[] = { FILETYPES };
	char buf[BUFSIZE];
	char *c;
	int i;

	/* Request */
	strclear(st->req_selector);
	strclear(st->req_realpath);
	strclear(st->req_query_string);
	strclear(st->req_referrer);
	sstrlcpy(st->req_local_addr, get_local_address());
	sstrlcpy(st->req_remote_addr, get_peer_address());
	/* strclear(st->req_remote_host); */
	st->req_filetype = DEFAULT_TYPE;
	st->req_protocol = PROTO_GOPHER;
	st->req_filesize = 0;

	/* Output */
	st->out_width = DEFAULT_WIDTH;
	st->out_charset = DEFAULT_CHARSET;

	/* Settings */
	sstrlcpy(st->server_root, DEFAULT_ROOT);
	sstrlcpy(st->server_host_default, DEFAULT_HOST);

	if ((c = getenv("HOSTNAME")))
		sstrlcpy(st->server_host, c);
	else if ((gethostname(buf, sizeof(buf))) != ERROR)
		sstrlcpy(st->server_host, buf);

	st->server_port = DEFAULT_PORT;

	st->default_filetype = DEFAULT_TYPE;
	sstrlcpy(st->map_file, DEFAULT_MAP);
	sstrlcpy(st->tag_file, DEFAULT_TAG);
	sstrlcpy(st->cgi_file, DEFAULT_CGI);
	sstrlcpy(st->user_dir, DEFAULT_USERDIR);
	strclear(st->log_file);

	st->hidden_count = 0;
	st->filetype_count = 0;
	strclear(st->filter_dir);
	st->rewrite_count = 0;

	strclear(st->server_description);
	strclear(st->server_location);
	strclear(st->server_platform);
	strclear(st->server_admin);

	/* Session */
	st->session_timeout = DEFAULT_SESSION_TIMEOUT;
	st->session_max_kbytes = DEFAULT_SESSION_MAX_KBYTES;
	st->session_max_hits = DEFAULT_SESSION_MAX_HITS;

	/* Feature options */
	st->opt_vhost = TRUE;
	st->opt_parent = TRUE;
	st->opt_header = TRUE;
	st->opt_footer = TRUE;
	st->opt_date = TRUE;
	st->opt_syslog = TRUE;
	st->opt_magic = TRUE;
	st->opt_iconv = TRUE;
	st->opt_query = TRUE;
	st->opt_caps = TRUE;
	st->opt_shm = TRUE;
	st->opt_root = TRUE;
	st->debug = FALSE;

	/* Load default suffix -> filetype mappings */
	for (i = 0; filetypes[i]; i += 2) {
		if (st->filetype_count < MAX_FILETYPES) {
			sstrlcpy(st->filetype[st->filetype_count].suffix, filetypes[i]);
			st->filetype[st->filetype_count].type = *filetypes[i + 1];
			st->filetype_count++;
		}
	}
}