Exemplo n.º 1
0
off_t __plseek(int fd, off_t offset, int whence) {
    idStream *is = getStreamData(getpid(), fd);
    if(!is)
        return -1;

    UNUSED(offset);
    UNUSED(whence);
    return /*lseek(is->fd, offset, whence)*/-1;
}
Exemplo n.º 2
0
int createPipe(int size, int flags)
{
    Spipe *p = newSpipeData();
    if(!p)
        return -1;
    int pid = getpid();

    enterProcessCriticalCode(pid);
    int fd = open_fd();
    if(fd < 0)
        return fd;
    idStream *is = getStreamData(getpid(), fd);

    createMutex(&p->locker);
    p->memory = malloc(size+4);
    p->seek = 0;
    p->offset = 0;
    p->size = size;
    p->ready_read_wid = createAdvWaitCond("waiter", 0);
    p->ready_write_wid = createAdvWaitCond("waiter", 0);
    p->fully_flushed_wid = createAdvWaitCond("waiter", 0);
    p->fully_empty_wid = createAdvWaitCond("waiter", 0);
    p->flags = flags;

    is->fd = p->id;
    is->type = PIPE_STREAM;
    is->mode = O_RDWR;
    is->pid = pid;
    is->read = __pread;
    is->write = __pwrite;
    is->flush = __pflush;
    is->lseek = __plseek;
    is->close = __pclose;

    wakeOneWaitCond(p->ready_write_wid);
    leaveProcessCriticalCode(pid);

    return fd;
}
Exemplo n.º 3
0
	ServerProtocol *ServerHttp2::process()
	{
		struct Request req;
		req.timeout = std::chrono::milliseconds(15000);
		req.protocol_variant = Transfer::ProtocolVariant::HTTP_2;

		Http2::ConnectionData conn;

		sendEmptySettings(
			this->sock,
			req.timeout,
			conn,
			Http2::FrameFlag::EMPTY
		);

		if (getClientPreface(this->sock, req.timeout) == false) {
			constexpr uint32_t last_stream_id = 0;

			goAway(
				this->sock,
				req.timeout,
				conn,
				last_stream_id,
				Http2::ErrorCode::PROTOCOL_ERROR
			);

			return this;
		}

		conn.client_settings = Http2::ConnectionSettings::defaultSettings();
		conn.server_settings = Http2::ConnectionSettings::defaultSettings();

		std::vector<char> buf(conn.server_settings.max_frame_size);

		std::unordered_map<uint32_t, Http2::IncStream> streams {
			{ 0, Http2::IncStream(0, conn) }
		};

		Http2::IncStream &primary = streams.find(0)->second;
		this->stream = &primary;

		size_t streams_process_count = 0;
		uint32_t last_stream_id = 0;

		Http2::FrameMeta meta {};
		long read_size = 0;

		do {
			if (getNextHttp2FrameMeta(this->sock, req.timeout, buf, meta, read_size) == false) {
				break;
			}

			const uint8_t *addr = reinterpret_cast<const uint8_t *>(
				buf.data()
			) + Http2::FRAME_HEADER_SIZE;

			const uint8_t *end = addr + meta.length;

			if (meta.stream_id > last_stream_id) {
				last_stream_id = meta.stream_id;
			}

			Http2::IncStream &stream = getStreamData(streams, meta.stream_id, conn);

			if (Http2::StreamState::CLOSED == stream.state) {
				rstStream(this->sock, req.timeout, stream, Http2::ErrorCode::STREAM_CLOSED);
				continue;
			}

			if (meta.type != Http2::FrameType::CONTINUATION) {
				stream.frame_type = meta.type;
			}

			Http2::ErrorCode result = Http2::ErrorCode::NO_ERROR;

			switch (stream.frame_type)
			{
			case Http2::FrameType::DATA:
			{
				result = parseHttp2Data(meta, stream, addr, end);

				stream.window_size_inc -= meta.length;

				if (stream.reserved)
				{
					DataVariant::DataReceiver *dr = reinterpret_cast<DataVariant::DataReceiver *>(stream.reserved);

					if (stream.window_size_inc - long(conn.server_settings.max_frame_size) <= 0)
					{
						size_t update_size = conn.server_settings.initial_window_size +
							(dr->full_size - dr->recv_total) - size_t(stream.window_size_inc);

						if (update_size > Http2::MAX_WINDOW_UPDATE) {
							update_size = Http2::MAX_WINDOW_UPDATE;
						}

						sendWindowUpdate(this->sock, req.timeout, stream, uint32_t(update_size) );
						sendWindowUpdate(this->sock, req.timeout, primary, uint32_t(update_size) );

						stream.window_size_inc += update_size;
					}
				}

				break;
			}

			case Http2::FrameType::HEADERS:
			{
				result = parseHttp2Headers(meta, stream, addr, end);

				if (meta.flags & Http2::FrameFlag::END_HEADERS)
				{
					Transfer::request_data *rd = static_cast<Transfer::request_data *>(&stream);

					stream.reserved = createDataReceiver(rd, this->settings.variants);

					if (stream.reserved) {
						DataVariant::DataReceiver *dr = reinterpret_cast<DataVariant::DataReceiver *>(stream.reserved);
						dr->reserved = new std::string();
					}
				}

				break;
			}

			case Http2::FrameType::PRIORITY:
				result = Http2::ErrorCode::NO_ERROR;
				break;

			case Http2::FrameType::RST_STREAM:
				result = parseHttp2rstStream(meta, stream, addr, end);
				break;

			case Http2::FrameType::SETTINGS:
			{
				result = parseHttp2Settings(meta, stream, addr, end);

				if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false)
				{
					conn.decoding_dynamic_table.changeHeaderTableSize(conn.client_settings.header_table_size);
					conn.decoding_dynamic_table.changeMaxHeaderListSize(conn.client_settings.max_header_list_size);

					sendEmptySettings(this->sock, req.timeout, conn, Http2::FrameFlag::ACK);
				}

				break;
			}

			case Http2::FrameType::PUSH_PROMISE:
				result = Http2::ErrorCode::NO_ERROR;
				break;

			case Http2::FrameType::PING:
			{
				result = parseHttp2Ping(meta);

				if (Http2::ErrorCode::NO_ERROR == result && (meta.flags & Http2::FrameFlag::ACK) == false)
				{
					const uint64_t ping_data = *reinterpret_cast<const uint64_t *>(addr);
					ping(this->sock, req.timeout, conn, ping_data);
				}

				break;
			}

			case Http2::FrameType::GOAWAY:
				result = parseHttp2GoAway(meta, stream, addr, end);
				break;

			case Http2::FrameType::WINDOW_UPDATE:
				result = parseHttp2WindowUpdate(meta, stream, addr, end);
				break;

			default:
				result = Http2::ErrorCode::PROTOCOL_ERROR;
				break;
			}

			if (result != Http2::ErrorCode::NO_ERROR)
			{
				stream.state = Http2::StreamState::CLOSED;

				rstStream(this->sock, req.timeout, stream, result);

				// TODO: remove closed stream(s) from unordered map
			}
			else if ( (meta.flags & Http2::FrameFlag::END_STREAM) && meta.stream_id != 0)
			{
				stream.reserved = this->sock.get_tls_session();

				sockets.lock();

				sockets.emplace(
					std::tuple<Socket::Socket, Http2::IncStream *> {
						Socket::Socket(this->sock.get_handle() ),
						&stream
					}
				);

				sockets.unlock();

				this->controls.eventProcessQueue->notify();

				++streams_process_count;
			}
		}
		while (Http2::StreamState::CLOSED != primary.state);

		while (conn.sync.completed.load() < streams_process_count) {
			conn.sync.event.wait();
		}

		goAway(
			this->sock,
			req.timeout,
			conn,
			last_stream_id,
			Http2::ErrorCode::NO_ERROR
		);

		for (auto &pair : streams) {
			destroyDataReceiver(pair.second.reserved);
		}

		return this;
	}
Exemplo n.º 4
0
int __pclose(int fd) {
    idStream *is = getStreamData(getpid(), fd);
    if(!is)
        return -1;
    return closePipe(is->fd);
}
Exemplo n.º 5
0
int __pflush(int fd) {
    idStream *is = getStreamData(getpid(), fd);
    if(!is)
        return -1;
    return 0;
}
Exemplo n.º 6
0
ssize_t __pwrite(int fd, const void *data, size_t size) {
    idStream *is = getStreamData(getpid(), fd);
    if(!is)
        return -1;
    return writePipe(is->fd, data, size);
}
Exemplo n.º 7
0
ssize_t __pread(int fd, void *data, size_t size) {
    idStream *is = getStreamData(getpid(), fd);
    if(!is)
        return -1;
    return readPipe(is->fd, data, size);
}