Often a server will need to know who sent it a message.
There are a number of reasons for this:
- accounting
- access control
- context association
- class of service
- compatibility
- etc.
It would be cumbersome (and a security hole) to have the client provide
this information with each and every message sent.
Therefore, there's a structure filled in by the
kernel whenever the MsgReceive() function unblocks
because it got a message.
This structure is of type
struct _msg_info,
and
contains the following:
struct _msg_info
{
uint32_t nd;
uint32_t srcnd;
pid_t pid;
int32_t tid;
int32_t chid;
int32_t scoid;
int32_t coid;
int16_t priority;
int16_t flags;
ssize64_t msglen;
ssize64_t srcmsglen;
ssize64_t dstmsglen;
};
You pass it to the MsgReceive() function as the last argument.
If you pass a NULL, then nothing happens.
(The information can be retrieved later via the
MsgInfo()
call, so it's not gone forever!)
Let's look at the fields:
- nd, srcnd, pid, and tid
- Node Descriptors, process ID, and thread ID of the client.
(Note that nd is the receiving node's node descriptor for
the transmitting node; srcnd is the transmitting node's
node descriptor for the receiving node. There's a very good reason
for this :-), which we'll see below in Some notes on NDs.)
- priority
- The priority of the sending thread.
- chid, coid
- Channel ID that the message was sent to, and the connection ID used.
- scoid
- Server Connection ID.
This is an internal identifier used by the kernel to route
the message from the server back to the client.
You don't need to know about it, except for the interesting
fact that it will be a small integer that uniquely represents the
client.
- flags
- Contains a variety of flag bits, including the following:
- _NTO_MI_BITS_64 and _NTO_MI_BITS_DIFF tell you that
the sender is using a 64-bit architecture, or a different word-size architecture than you're using.
- _NTO_MI_ENDIAN_BIG and _NTO_MI_ENDIAN_DIFF tell you about the
endian-ness of the sending machine (in case the message came over the network from a machine
with a different endian-ness).
- _NTO_MI_NET_CRED_DIRTY is used internally.
- We'll look at _NTO_MI_UNBLOCK_REQ in the section
Using the _NTO_MI_UNBLOCK_REQ, below.
If you determine that your program is incompatible with the sender, you can return an error such as
ENOTSUP.
See
Replying with no data, or an errno
later in this chapter.
- msglen
- Number of bytes received.
- srcmsglen
- The length of the source message, in bytes, as sent by the client.
This may be greater than the value in msglen, as would be
the case when receiving less data than what was sent.
- dstmsglen
- The length of the client's reply buffer, in bytes.