1
\chapter{Using the H\_IN: an example}\label{chap:h-in-example}
2
\begin{quote}
3
  Nihil nobis metuendum est, pr{\ae}ter metum ipsum.\\
4
  -- Julius Caesar
5
\end{quote}
6
7
In chapter~\ref{chap:h-in}, we discussed the {\tt h\_in}-API and in
8
chapter~\ref{chap:messages} we went through the message syntax. 
9
10
In this chapter we combine and apply that knowledge in a
11
simple\footnote{simple in concept, not so much in implementation} example. We
12
hope that this clarifies the material shown before, and also answers some of
13
the greater questions of where this all leads to.
14
15
{\bf Caveat lector:} this chapter discusses the details of programming NoTA
16
using the {\tt H\_IN}-API directly. This is good for understanding the
17
backgrounds, but you may not need all of that. You can use the {\bf stub
18
  generator} (discussed in chapter~\ref{chap:stubgen}) instead, which hides
19
many of the low-level details
20
21
The previous chapters are a prerequisite for understanding this chapter; you
22
might also find it useful to have the {\tt h\_in}-man pages available. The
23
man-pages are part of your NoTA-installation; see
24
appendix~\ref{chap:installation} for details.
25
26
\section{Caesar cypher}\index{Caesar cypher}
27
To gain some good understanding of the {\tt h\_in} \index{high-level
28
interconnect}, simple examples work best. So, we hope that you can forgive
29
us that the example is rather useless as a real-world use case. And, already
30
in the simple example, the implementation gets rather complicated.
31
32
For the example in this chapter, we will use a service node (SN) that
33
implements a {\em Caesar cypher}\footnote{for some background, see: {\tt
34
http://en.wikipedia.org/wiki/Caesar\_cipher}}\index{Caesar cypher} - a simple
35
encryption technique where the characters in a string (circularly) shifted
36
over some fixed number of positions up or down the alphabet.
37
38
Now, suppose we want to implement a server that can handle the encryption
39
operation. It should handle messages\index{message} of the form:
40
\begin{verbatim}
41
     caesar_crypt_req (bdat1 text, int8 shift);
42
\end{verbatim}
43
Some notes:
44
\begin{itemize}
45
\item it would be natural to think of this as a {\em function}, but for our
46
  purposes, it's better to think of as a {\em message}. For example, it does
47
  not have a return value;
48
\item we call the function {\tt caesar\_crypt\_{\bf req}} to emphasize that it
49
  is a {\bf request}; note that it can be used for both encryption and
50
  decryption;
51
\item we only support the 26 lower-case characters in the English
52
  alphabet, so {\tt shift} parameter has an effective range of [-25, 25].
53
\end{itemize}
54
55
Now, after the service node has received such a {\tt
56
caesar\_crypt\_req}-message and all the parameters are correct, it can execute
57
the operation and respond with a message:
58
\begin{verbatim}
59
    caesar_crypt_rsp (bdat1 text);
60
\end{verbatim}
61
Of course, it could be that we received {\em incorrect} parameters. For
62
example, the text should not contain a characters outside the {\tt
63
  [a-z]}-range, and the shift parameter should be in range as well. In case of
64
such a problem, we can respond with an error notification:
65
\begin{verbatim}
66
    caesar_crypt_error_rsp (uint8 code);
67
\end{verbatim}
68
69
Summarizing, there are three messages: two to be handled by the server (SN),
70
one by the client. 
71
72
\section{Implementation}
73
Now, let's look at implementing an AN and an SN for this, to show how it all
74
works. For our implementation, we use plain C, and we're assuming a
75
UNIX/Linux-like environment. We need to do the following:
76
\begin{itemize}
77
    \item write the common definitions;
78
    \item write the service node;
79
    \item write the client node.
80
\end{itemize}
81
You could choose a different order, of course.
82
83
\subsection{Common definitions}
84
The first thing we should do is to identify the common things that are needed
85
for both AN and SN, put those in a common header file  {\tt caesar-common.h}.
86
87
The first thing we need to do, is to define an address\footnote{In a more
88
realistic case, you could get the address from the resource manager (discussed
89
in chapter~\ref{chap:rm})} for the SN -- a {\tt nota\_addr\_t} that the AN can
90
use to find it, similar to having a IP-number in a network.
91
92
For this example, we simply hard-code it. As we saw in in the previous
93
chapter, a NoTA-address is defined as an array of two numbers. So, we define
94
our service address (arbitrarily):
95
\begin{lstlisting}
96
        #define CAESAR_SN_ADDRESS   {1,1}
97
\end{lstlisting}
98
The other common definitions are the signal-id's for the three messages we
99
need:
100
\begin{lstlisting}
101
/* signal id's: */
102
/* (1) implemented by the SN */
103
#define	CAESAR_CRYPT_REQ_SIGID        0x0001
104
105
/* (2) implemented by the AN */
106
#define	CAESAR_CRYPT_RSP_SIGID        0x0002  
107
#define	CAESAR_CRYPT_ERROR_RSP_SIGID  0x0003
108
\end{lstlisting}
109
110
We also declare the \texttt{caesar\_handle\_message}-function, which we can
111
reuse in both AN and SN.
112
113
That's all for {\tt caesar-common.h}.
114
115
\subsection{Writing a service node}
116
117
\subsubsection{Service node socket handling}
118
Now, let's see how we can write a service node\index{service node}. If you
119
have ever written servers using BSD-sockets, this will all look very
120
familiar. If you are not familiar with BSD-sockets, see
121
\cite{Beej2009}\footnote{direct URL: http://www.beej.us/guide/bgnet/} for a
122
gentle introduction.
123
124
In the following, we'll go through this implementation. The full source code
125
is available in appendix~\ref{chap:example}; here we show a slightly shorter
126
version -- without error checking. The example {\bf has} error-checking
127
though, as it is very important, especially since examples are sometimes
128
copy-pasted for use in 'real' programs...
129
130
The first thing is {\em not} in BSD though --  we start by getting a NoTA
131
instance pointer:
132
\begin{lstlisting}
133
    h_in_t *inst;
134
    inst = Hgetinstance ();
135
\end{lstlisting}
136
137
Easy. If that went well, we can ask NoTA to give us a a socket.
138
\begin{lstlisting}
139
    int sock;
140
    sock = Hsocket (inst, AF_NOTA, SOCK_SEQPACKET, 0);
141
\end{lstlisting}
142
143
Note that we are using {\tt SOCK\_SEQPACKET} here; as explained in the
144
previous chapter, this is the best choice when a socket is meant for messages
145
as in this case, as the system guarantees that we get the {\bf whole message
146
in one go}.
147
148
The alternative, {\tt SOCK\_STREAM}, is more efficient for sending bulk data,
149
such as files and multimedia content.
150
151
Now we have our socket, and like to {\em bind} it to some address - we're
152
telling the system that this sockets has some particular address. For that,
153
there is the {\tt Hbind}-function:
154
\begin{lstlisting} 
155
  nota_addr_t addr = CAESAR_SN_ADDRESS;
156
  Hbind (inst, sock, (struct sockaddr*)&addr, sizeof(addr));
157
\end{lstlisting}
158
This will bind our socket to {\tt CAESAR\_SN\_ADDRESS}, so the AN can find it.
159
160
Before that, we have to put the socket in {\em listening mode}, using {\tt
161
  Hlisten}:
162
\begin{lstlisting}
163
   Hlisten (inst, sock, 1);
164
\end{lstlisting}
165
We set the last {\em backlog} parameter to 1, but it's not really important
166
in this simple example.
167
168
Now, we have done all the preparatory things, and we can start listening on
169
the socket for incoming messages. We use the simplest possible way of doing
170
that: using {\tt Haccept}:
171
\begin{lstlisting}
172
   int peersock;
173
   peersock = Haccept (inst, sock, NULL, NULL);
174
\end{lstlisting}
175
176
This function will {\bf block} (i.e., wait) for an incoming connection. When
177
there is an incoming connection, it will return a socket in {\tt peersock},
178
which is the socket over which the communication with the other side (the
179
peer) can take place.
180
181
Note that the last two parameters are {\tt NULL}, as they are ignored in NoTA
182
(not in BSD) - see the previous chapter for the details.
183
184
After we accepted a connection (with {\tt Haccept}), we need to decode the
185
bytes we get and figure out what to do with them. This is discussed in the
186
next paragraph; here, we continue with the discussion of the socket handling.
187
188
Finally, when we are done with our with our SN, we can close the socket with
189
{\tt Hclose}: 
190
\begin{lstlisting}
191
  Hclose (inst, sock);
192
\end{lstlisting} 
193
In this example, we never really reach that code, as the SN will only be
194
terminated by manual interaction (e.g.., {\tt Ctrl-C}), and all it's sockets
195
will be closed then. 
196
197
\subsubsection{Service node message handling}\label{subsubsec:snmsghandling}
198
So, we accepted a connection from 'the other side'. We'd now like to read the
199
bytes available, and decode that into a message (if needed, consult
200
chapter~\ref{chap:messages} for the details on coding/decoding).
201
202
In both the service node and the application node, we will need message
203
handling, so we define a function \texttt{caesar\_get\_message} in
204
\texttt{caesar-common.h}; see the appendix for the actual code, but you will
205
probably agree that it requires some careful coding to read NoTA-messages.
206
207
\texttt{caesar\_get\_message} returns us the signal-id for the received
208
message; we then need to write the code for the various message handling
209
functions to extract the parameters from the data. This is rather tedious, as
210
we have to be check at each step; we can never assume that the data is
211
correct. For example, BDAT-values have their length embedded --if we blindly
212
accept that value, it would easily lead to buffer overflows\index{buffer
213
overflow}.
214
215
We defined only one possible message for the service node: 
216
\begin{verbatim}
217
  caesar_crypt_req (bdat1 text, int8 shift);
218
\end{verbatim}
219
 
220
What would the corresponding bytes look like? Well:
221
\begin{itemize}
222
  \item the message should start with the typecode for a signal-id, followed
223
    by the signal-id itself. As we've seen, the typecode for a two-byte signal
224
    id is {\tt 0xa2}. And we defined the signal id as {\tt
225
      CAESAR\_CRYPT\_REQ\_SIGID} (value: {\tt 0x0001});
226
  \item then follows the {\tt text} parameter, the string in a {\tt BDAT1}; this will
227
    be encoded as {\tt 0x41} followed by one byte for the {\em length}, and
228
    then the bytes for the string itself;
229
  \item finally, there is the {\tt shift} parameter, which is in {\tt INT8};
230
    this will be encoded as {\tt 0x21} followed by one byte for the value.
231
\end{itemize}
232
233
To put it all together:
234
\begin{tabular} {| l | l | l |}
235
  \hline
236
  {\tt 0xa2} {\tt 0x0001} & {\tt 0x41} {\em n} {\em $bytes_{1\dots n}$} & {\tt
237
    0x21} {\em byte} \\
238
  \hline
239
\end{tabular}
240
241
Using this information, we can read the bytes from the socket using {\tt
242
Hrecv}. This is rather tedious, as we must verify that we get what we are
243
supposed to get. The Service Node cannot make any assumptions on the validity
244
of the data.
245
246
\subsubsection{{\tt caesar-sn.c}}
247
Now, we have discussed all the relevant details for writing the Caesar service
248
node; see {\tt caesar-sn.c} in appendix~\ref{chap:example}. Additionally,
249
appendix~\ref{chap:building} has information on how to build the examples,
250
link with the NoTA-libraries and so on.
251
252
\subsection{Writing an application node}\label{subsec:appnode}
253
We have seen how we can write the service node for our Caesar example. We now
254
continue with the application node\index{application node}. As before, we go
255
through the relevant details here, and then refer to
256
appendix~\ref{chap:example} for the actual source code. And as before, the
257
code is bit tedious because of the manual processing of the bytes in the
258
message.
259
260
We go through the code once more. We omit the error handling here, but there
261
{\bf is} error handling in the example code. The first implementation steps
262
for the AN are the same as those for the SN: we need to get an instance
263
pointer\index{instance pointer} and a socket\index{socket}:
264
265
\begin{lstlisting}
266
 h_in_t *inst;
267
 int sock;
268
269
 inst = Hgetinstance ();
270
 sock = Hsocket (inst, AF_NOTA, SOCK_SEQPACKET, 0);
271
\end{lstlisting}
272
273
Again, we are using {\tt SOCK\_SEQPACKET}, which is the best choice for NoTA
274
messages.
275
276
For an application node, we usually don't care about its (source) port;
277
therefore it is {\em not necessary} to call {\tt Hbind} to connect it to a
278
particular port. We'll happily leave that to NoTA. Also, we don't need to call
279
{\tt Hlisten} to put our socket in {\em listening mode}, because the AN
280
initiates the connection.
281
282
We can now connect to the Service Node using {\tt Hconnect}:
283
\begin{lstlisting}
284
  nota_addr_t addr = CAESAR_SN_ADDRESS;
285
  Hconnect (inst, sock, (struct sockaddr*)&addr, sizeof(addr));
286
\end{lstlisting}
287
288
When {\tt Hconnect} has succeeded, we are ready to send our messages to the
289
SN. We have already seen how to {\em de}code a message in the discussion about
290
the service node; now we need to {\em en}code such a message.     
291
292
\subsubsection{Sending requests to the service node}
293
Remember, the message for the service node looks like the following: 
294
\begin{verbatim}
295
  caesar_crypt_req (bdat1 text, int8 shift);
296
\end{verbatim}
297
Obviously, the message we sent should have the same format as the one the SN
298
is to receive; have a look at the details in
299
paragraph~\ref{subsubsec:snmsghandling}. As we have seen, the final result
300
looks like this:
301
\begin{tabular} {| l | l | l |}
302
  \hline
303
  {\tt 0xa2} {\tt 0x0001} & {\tt 0x41} {\em n} {\em $bytes_{1\dots n}$} & {\tt
304
    0x21} {\em byte} \\
305
  \hline
306
\end{tabular}
307
308
We can send these bytes to the SN using {\tt Hsend}. Refer to
309
appendix~\ref{chap:example} for the source code.
310
311
\subsubsection{Handling responses from the service node}
312
313
\section{Compiling and running the example}
314
Now, let's see how we can run the Caesar cypher example.
315
\subsection{Compilation}
316
The first step is to {\em compile} the example. Please refer to
317
appendix\ref{chap:building} for general information about compiling NoTA-based
318
software, and see appendix~\ref{chap:example} for a {\tt Makefile} for the
319
Caesar cypher example. 
320
\subsection{Running}
321
TODO
322
323
\section{Questions}
324
To test your understanding of this chapter, you could try to answer some of
325
these questions. You can find the answers to these question in
326
appendix~\ref{chap:answers}.
327
\begin{enumerate}
328
    \item In the examples, we read from the socket using {\tt MSG\_WAITALL};
329
  however, we can be sure that it won't block in all but the first {\tt
330
  Hrecv}. Why can we be sure? (Hint: think about the kind of socket this is).
331
\item NoTA nodes (ANs and SNs) can communicate fully asynchronously; so how
332
  can the AN know which of the {\tt caesar\_crypt\_rsp} (or {\tt
333
    caesar\_crypt\_error\_rsp}) is a response to which {\tt
334
    caesar\_crypt\_rsp}?  (Hint: this is a trick question)
335
    \item Suppose that someone complains that our Caesar cypher is not secure
336
  enough. For extra security, we'd like to add the functionality to {\em
337
  revert} a text too. Adapt the Service Node such that it accepts a second
338
  message
339
\begin{verbatim}
340
    caesar_revert_req (bdat1 text);
341
\end{verbatim}
342
  which will cause the text to be reverted (for the signal id, you can use
343
  {\tt 0x0004}). Also, update the AN to send this message.
344
\item (Bonus question) The Caesar cypher with a shift parameter of 13 is
345
  better known as {\tt ROT-13}. What's the longest word you can find that has
346
  the property that its ROT-13 encoding is equal to the {\em reverse} of the
347
  word?
348
\end{enumerate}