📄 section-server.tex
字号:
\chapter{The name server protocol}
\label{sect:name-protocol}
The name server is a program that listens on a known socket-port\footnote{We
write socket-ports to distinuish tcp/ip port numbers for sockets,
from higher-level YARP Ports.}
on a known machine.
%
It tracks information about Ports in the YARP Network.
%
%
If you know the name
of a Port, you can query the name server to learn how to communicate
with that Port.
The name server maintains a set of records, whose key is a text
string. The contents are at least hostname, socket number, and
protocol name. This describes how to contact the port. There is also
a description of what kinds of connections the port can or is willing
to participate in. The set of protocols the port can accept an
incoming data connection for are named - this is the ``accept'' set.
The set of protocols the port can create an outgoing data connection
for are also named - this is the ``offer'' set.
For example, suppose you want to communicate with a Port called
``/write''. The first step is to ask the name server about this
Port. The name server runs on a known socket-port of a known machine,
listening for tcp connections.
It is usually queried through a library call, but for illustration
purposes we describe
querying it using telnet. Suppose the name server is running on
machine 192.168.0.3 and listening on socket-port 10000 (we will
discuss a procedure for discovering this information later).
Then we can query the name server about the Port /write as follows:
\begin{code}
telnet 192.168.0.3 10000
\end{code}
%
The name server should start listening -- if the connection is refused,
something is wrong. Once the connection is made, type:
%
\begin{code}
NAME_SERVER query /write
\end{code}
%
The server will respond with something of the form:
%
\begin{code}
registration name /write ip 5.255.112.227 port 10001 type tcp
*** end of message
\end{code}
%
So the Port named /write is listening on the machine with
IP address 5.255.112.227, on port 10001, and it expects TCP
connections.
How do Ports get registered in the same place? Here's how to create a
(fake) registration
manually (usually it is of course done through a library call).
Telnet to the name server as before, and type:
%
\begin{code}
NAME_SERVER register /write
\end{code}
%
The server will respond with something of the form:
%
\begin{code}
registration name /write ip 5.255.112.227 port 10001 type tcp
*** end of message
\end{code}
The name server takes responsibility for allocating
socket-ports and identifying the machine the Port runs on.
Note that the protocol described here for communicating with the name
server is a YARP2 feature. YARP1 used a different, binary protocol.
The human-readable protocol has been introduced to make the system
more transparent and easier to step through.
For yarp utilities to correctly discover how
to contact the name server,
there should be a file namer.conf in the directory \$HOME/.yarp/conf/
(or in the directory specified by an environment variable \$YARP\_ROOT)
that looks like this:
\begin{code}
192.168.0.3 10000
\end{code}
This gives the machine and socket-port that the name server is assumed
to be running on.
If this file does not exist, or is incorrect, yarp utilities will
attempt to contact the nameserver using multi-cast broadcasts to
224.2.1.1 port 10001 (this is a YARP2 feature, not available in
YARP1). If the nameserver is running a machine reachable from
multi-cast, it will respond with its ``true'' tcp address, which will
then be used by the utility. The configuration file will be updated
automatically for future reference. The multi-cast protocol is
identical to the normal tcp protocol. Clients can broadcast
``NAME\_SERVER query root'' to trigger the name server to send a record
of the form ``registration name root ip ADDRESS port NUMBER type
CARRIER''. The ``root'' record is a special record corresponding to
the name server. Multi-cast broadcasts should not generally be used
by clients to communicate with the name server, since the output of
the name server is not tagged with the recipient, so there is the
potential for cross-talk.
\newusage{}
\usage{NAME\_SERVER query PORT}
Requests registration information for the named port. Response is of
the following form:
\begin{code}
registration name PORT ip ADDRESS port NUMBER type CARRIER
*** end of message
\end{code}
For example:
\begin{code}
registration name /write ip 5.255.112.227 port 10001 type tcp
*** end of message
\end{code}
If there is no registration for the port, the registration line
is omitted, and instead the response is simply:
\begin{code}
*** end of message
\end{code}
\newusage{}
\usage{NAME\_SERVER register PORT}
Requests creation of registration information for the named port.
Response is of the following form:
\begin{code}
registration name PORT ip ADDRESS port NUMBER type CARRIER
*** end of message
\end{code}
For example:
\begin{code}
registration name /write ip 5.255.112.227 port 10001 type tcp
*** end of message
\end{code}
%
Optionally, the user can take responsibility for more, and
issue commands in one of the following forms:
\begin{code}
NAME_SERVER register PORT CARRIER
NAME_SERVER register PORT CARRIER IP
NAME_SERVER register PORT CARRIER IP NUMBER
\end{code}
Any value (including the port name) can be replaced by ``...'' to leave it
up to the name-server to choose it. For example:
\begin{code}
NAME_SERVER register ... tcp 127.0.0.1 8080
\end{code}
Gives something of the form:
\begin{code}
registration name /tmp/port/1 ip 127.0.0.1 port 8080 type tcp
*** end of message
\end{code}
If you choose to set the ip yourself, be careful -- there is the
possibility of problems with multiple ways to identify the same
machine. It is best to let the name server choose a name,
which it should do in a consistent way. If a machine has
multiple ip addresses on multiple networks, that can be
handled -- see the
discussion of the {\tt ips} property in the section on {\tt set}.
That is important for the purposes of controlling which
network is used for connections from one port to another.
\newusage{}
\usage{NAME\_SERVER unregister PORT}
Removes registration information for the named port.
Response is of the following form:
\begin{code}
*** end of message
\end{code}
\newusage{}
\usage{NAME\_SERVER list}
Gives registration information of all known ports.
Response is of the following form:
\begin{code}
registration name /write ip 130.251.4.159 port 10021 type tcp
registration name /read ip 130.251.4.159 port 10031 type tcp
registration name /tmp/port/4 ip 130.251.4.159 port 10011 type tcp
registration name /tmp/port/3 ip 130.251.4.52 port 10021 type tcp
registration name /tmp/port/2 ip 130.251.4.52 port 10011 type tcp
registration name /tmp/port/1 ip 130.251.4.159 port 10001 type tcp
*** end of message
\end{code}
\newusage{}
\usage{NAME\_SERVER set PORT PROPERTY VALUE1 VALUE2 \ldots}
The name server can store extra properties of a port, beyond the
bare details associated with registration. The {\tt set} command
is used to do this. For example, the command:
\begin{code}
NAME_SERVER set /write offers tcp udp mcast
\end{code}
Gets the following response:
\begin{code}
port /write property offers = tcp udp mcast
\end{code}
The {\tt get} and {\tt check} commands can then be used to query
such properties.
There are some special properties used by YARP. Property ``ips''
can list multiple identifiers of a machine. Property ``offers''
lists carriers that an output port can support. Propery ``accepts''
lists carriers that an input port can support.
\newusage
\usage{NAME\_SERVER get PORT PROPERTY}
Gets the values of a stored property. For example,
after the {\tt set} command example shown earlier, the command:
\begin{code}
NAME_SERVER get /write offers
\end{code}
Returns the following response:
\begin{code}
port /write property offers = tcp udp mcast
\end{code}
\newusage
\usage{NAME\_SERVER check PORT PROPERTY VALUE}
Checks if a stored property can take the given value. For example,
after the {\tt set} command example shown earlier, the command:
\begin{code}
NAME_SERVER check /write offers tcp
\end{code}
Returns the following response:
\begin{code}
port /write property offers value tcp present true
\end{code}
\newusage
\usage{NAME\_SERVER route PORT1 PORT2}
Finds a good way to connect an output port to an input port, based
on the carriers they have in common (preferred carriers can optionally
be added to this command in decreasing order of preference) and
which carriers are physically possible (for example, `shmem'
requires ports to be on the same machine, and `local' requires
ports to belong to threads with a shared memory space).
For example, the command:
\begin{code}
NAME_SERVER route /write /read
\end{code}
Returns the following response:
\begin{code}
port /write route /read = shmem://read
\end{code}
Suggesting that shmem is the best carrier to use.
%% \begin{codecase}{NAME\_SERVER check PORT PROPERTY VALUE}
%% Not yet documented.
%% \end{codecase}
%% \begin{codecase}{NAME\_SERVER match PORT PROPERTY VALUE}
%% Not yet documented.
%% \end{codecase}
%% \begin{codecase}{NAME\_SERVER connect}
%% Not yet documented.
%% \end{codecase}
%% \begin{codecase}{quit}
%% Not yet documented.
%% \end{codecase}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -