6 Low-level Network Layer
This module re-exports all bindings from the "network/message.ss"
and "network/event-loop.ss" modules.
6.1 Protocol Messages
(require (planet "message.ss" ("murphy" "9p.plt" 1 0) "network")) |
Structures and utilities to represent messages exchanged between 9P
clients and servers.
See
intro(9P)
for the original protocol message definition overview.
6.1.1 Messages
The base type of all 9P protocol messages.
(struct | | (message:t message) | | () | | | #:transparent) |
|
The base type of all 9P protocol messages initiating a request.
These messages are normally only transmitted from the client to the server.
(struct | | (message:r message) | | () | | | #:transparent) |
|
The base type of all 9P protocol messages responding to a request.
These messages are normally only transmitted from the server to the client.
(struct | | (message:t:version message:t) | | (max-size version) | | | #:transparent) |
|
max-size : natural-number/c |
version : string? |
Protocol negotiation request. See
version(9P)
for more information.
(struct | | (message:r:version message:r) | | (max-size version) | | | #:transparent) |
|
max-size : natural-number/c |
version : string? |
Protocol negotiation response. See
version(9P)
for more information.
Request to open an authentication channel. See
auth(9P)
for more information.
(struct | | (message:r:auth message:r) | | (aqid) | | | #:transparent) |
|
aqid : qid? |
Authentication channel open response. See
auth(9P)
for more information.
Filesystem root attach request. See
attach(9P)
for more information.
(struct | | (message:r:attach message:r) | | (qid) | | | #:transparent) |
|
qid : qid? |
Attached filesystem root response. See
attach(9P)
for more information.
(struct | | (message:r:error message:r) | | (name) | | | #:transparent) |
|
name : string? |
Generic error response. See
error(9P)
for more information.
The only message that has no corresponding request message but may be
sent in response to most other requests.
(struct | | (message:t:flush message:t) | | (old-tag) | | | #:transparent) |
|
old-tag : natural-number/c |
Previous message flush request. See
flush(9P)
for more information.
The higher-level code in this 9P implementation handles this message
automatically.
(struct | | (message:r:flush message:r) | | () | | | #:transparent) |
|
Flushed previous message response. See
flush(9P)
for more information.
The higher-level code in this 9P implementation handles this message
automatically.
File walk request. See
walk(9P)
for more information.
(struct | | (message:r:walk message:r) | | (qids) | | | #:transparent) |
|
qids : (vectorof qid?) |
Walked file response. See
walk(9P)
for more information.
File open request. See
open(9P)
for more information.
(struct | | (message:r:open message:r) | | (qid i/o-unit) | | | #:transparent) |
|
qid : qid? |
i/o-unit : natural-number/c |
Opened file response. See
open(9P)
for more information.
File open as descriptor request. See
openfd(9P)
for more information.
The higher-level code in this 9P implementation doesn’t support this
message since it is impossible to implement when TCP sockets are used
as the transport layer.
Opened file open as descriptor response. See
openfd(9P)
for more information.
The higher-level code in this 9P implementation doesn’t support this
message since it is impossible to implement when TCP sockets are used
as the transport layer.
File creation request. See
create(9P)
for more information.
(struct | | (message:r:create message:r) | | (qid i/o-unit) | | | #:transparent) |
|
qid : qid? |
i/o-unit : natural-number/c |
Created file response. See
create(9P)
for more information.
Data read request. See
read(9P)
for more information.
(struct | | (message:r:read message:r) | | (data) | | | #:transparent) |
|
data : natural-number/c |
Read data response. See
read(9P)
for more information.
Data write request. See
write(9P)
for more information.
(struct | | (message:r:write message:r) | | (size) | | | #:transparent) |
|
size : natural-number/c |
Written data response. See
write(9P)
for more information.
File handle clunk request. See
clunk(9P)
for more information.
(struct | | (message:r:clunk message:r) | | () | | | #:transparent) |
|
Clunked file handle response. See
clunk(9P)
for more information.
(struct | | (message:t:remove message:t) | | (fid) | | | #:transparent) |
|
fid : natural-number/c |
File and handle remove request. See
remove(9P)
for more information.
(struct | | (message:r:remove message:r) | | () | | | #:transparent) |
|
Removed file and handle response. See
remove(9P)
for more information.
Directory entry information request. See
stat(9P)
for more information.
(struct | | (message:r:stat message:r) | | (stat) | | | #:transparent) |
|
stat : stat? |
Directory entry information response. See
stat(9P)
for more information.
(struct | | (message:t:wstat message:t) | | (fid stat) | | | #:transparent) |
|
fid : natural-number/c |
stat : stat? |
Directory entry information change request. See
wstat(9P)
for more information.
(struct | | (message:r:wstat message:r) | | () | | | #:transparent) |
|
Changed directory entry information response. See
wstat(9P)
for more information.
6.1.2 Input and Output
The maximum bytes size allowable for a protocol message.
read-message and write-message throw errors if the
messages they handle exceed this size.
The parameter is also used during protocol negotiation between client
and server. Inside the server, on threads handling client requests,
the parameter is set to the value negotiated with the client.
Reads a 9P message in binary format from the input port in.
Writes the given 9P message to the output port out
in binary format.
6.1.3 Packings
A table tracking message tag numbers that are in use in the current thread.
A 16 bit unsigned integer packing. Values produced and consumed by the
packing are contained within boxes. When a box containg #f is
packed, a random number that is not yet present as a key in
(current-tags) is selected, registered in the table with the
associated value #t and placed in the box.
If a tag needs to be generated but there are too many tags registered in
the table, tag/p raises a 9P filesystem exception with the
message EAGAIN.
A table tracking file identifiers that are in use in the current thread.
A 32 bit unsigned integer packing. Values produced and consumed by the
packing are contained within boxes. When a box containg #f is
packed, a random number that is not yet present as a key in
(current-fids) is selected, registered in the table with the
associated value #t and placed in the box.
If a tag needs to be generated but there are too many tags registered in
the table, tag/p raises a 9P filesystem exception with the
message EMFILE.
6.2 Event Loops
(require (planet "event-loop.ss" ("murphy" "9p.plt" 1 0) "network")) |
Basic event loops to implement 9P network clients and servers over
TCP sockets.
(start-client | | hostname | | | | | | [ | port-no | | | | | | | local-hostname | | | | | | | local-port-no]) | | → | | |
|
hostname : string? |
port-no : (integer-in 1 65535) = 564 |
local-hostname : (or/c string? #f) = #f |
local-port-no : (or/c (integer-in 1 65535) #f) = #f |
Starts a client event loop in a new thread managed by a new custodian
after establishing a TCP connection to the server specified by the
hostname and port-no and negotiating the 9P protocol
version.
Returns three values:
A request submitting procedure. You pass a message of type
message:t to the procedure, it creates a fresh reply
channel, communicates the message and the channel to the event
loop thread, waits for a reply on the channel and returns the
reply message of type message:r.
Replies of type message:r:error are automatically converted
into exceptions of type exn:fail:filesystem:9p.
Messages of type message:t:flush and message:r:flush
are handled automatically by converting from and to exceptions of
type exn:break.
A file identifier clearing procedure. File identifiers can be
auto-generated when serializing request messages for network transport
but they cannot be dropped from the table of current identifiers
fully automatically: In case you have allocated a file identifier
automatically but you do not clunk or remove it, for example because
the request message for which the identifier was created returned
an error response, you should call this procedure with the file
identifier as an argument to release the identifier for future
reuse.
The custodian managing the event loop thread and the network connection.
Simply shutdown the custodian to terminate the client event loop.
Starts a server event loop in a new thread managed by a new custodian
after starting to listen on a TCP socket for the specified hostname
and port-no. Another thread with a message processing loop is
spawned for every incoming connection.
Each of the message processors calls t-handler on incoming
messages of type message:t, again in a new thread for every
incoming request. Thus multiple requests from the same client can run
in parallel. When t-handler returns a response of type
message:r, that message is communicated back to the message
processor which sends it to the client. When t-handler raises
an exception of type exn:fail:filesystem:9p, it is caught and
converted into a in a response of type message:r:error.
t-handler should respond sensibly to breaks since client
requests to flush a message that has not been responded to will result
in a break being sent to the message’s handling thread.
t-handler is called in a dynamic environment with the following
differences to the one in which start-server was called:
current-custodian is parameterized to the custodian managing
the whole server event loop, max-message-size is parameterized
to the negotiated maximum message size of the current 9P connection,
current-tags is parameterized to #f,
current-fids is parameterized to a hash table that can be used
to track file identifiers. This hash table is the same for all request
handlers spawned for the same client connection. Initially it contains
a single entry mapping the file identifier 4294967295 to the
value #f. When the message processor for a client connection
terminates, it calls fid-cleanup on any values stored in the
hash table that are not #f.
start-server returns the custodian managing the event loop
threads and the network connections. Simply shutdown the custodian to
terminate the server event loop.