comp.lang.ada
 help / color / mirror / Atom feed
* gnat -xdr flag confusion.
@ 2023-07-04 10:56 magardner2010
  2023-07-04 11:39 ` Dmitry A. Kazakov
  0 siblings, 1 reply; 3+ messages in thread
From: magardner2010 @ 2023-07-04 10:56 UTC (permalink / raw)


I'm still working on the p2p one-to-many data streaming protocol thing 
(at https://github.com/smeagolthellama/szakdolgozat-notes/tree/main/ada) 
and I'm trying to get it to communicate with a C thing via the xdr 
protocol. I'm trying to transfer a Child_Set, where
```
     type Child_Number is range 0 .. 2;
     subtype Child_Index is Child_Number range 1 .. Child_Number'Last;

     type Child_Set is array (Child_Index) of GNAT.Sockets.Sock_Addr_Type;
```
With the help of chatGPT, I wrote the following xdr spec file:
```
const CHILD_NUMBER = 2;

typedef unsigned int uint32;
typedef unsigned char uint8;

enum family_type {
   FAMILY_INET = 0,
   FAMILY_INET6 = 1,
   FAMILY_UNIX = 2,
   FAMILY_UNSPEC = 3
};

union inet_addr_type switch (family_type family) {
   case FAMILY_INET:
     opaque sin_v4[4];
   case FAMILY_INET6:
     opaque sin_v6[16];
   default:
     void;
};

struct address_and_port{
   inet_addr_type addr;
   unsigned int port;
};

union sock_addr_type switch (family_type family) {
   case FAMILY_UNIX:
     string name<>;
   case FAMILY_INET:
     address_and_port anp4;
   case FAMILY_INET6:
     address_and_port anp6;
   case FAMILY_UNSPEC:
     void;
};

struct child_set {
   sock_addr_type child_set_array[CHILD_NUMBER];
};
```
and using rpcgen, generated a C thing to encode/decode the messages the 
ada program is sending.

However, if the ada code encodes the object with 'write, then it creates 
something about 4 bytes too short, and if I use 'output, it is parsed as 
starting with family_type 256, which is not a member of the enum. Given 
that the gnat documentation for the -xdr flag is literally two lines, I 
don't really know where to look for more information on what I'm doing 
wrong. My current hypotheses include the C code having the family type 
recorded too many times (but I don't know how to check or fix that in 
the .x file) or the ada code not encoding the data according to the xdr 
standard correctly (but I am using the flag, and neither 'write or 
'output fixes it).

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gnat -xdr flag confusion.
  2023-07-04 10:56 gnat -xdr flag confusion magardner2010
@ 2023-07-04 11:39 ` Dmitry A. Kazakov
  2023-07-06 17:32   ` magardner2010
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry A. Kazakov @ 2023-07-04 11:39 UTC (permalink / raw)


On 2023-07-04 12:56, magardner2010 wrote:

> However, if the ada code encodes the object with 'write, then it creates 
> something about 4 bytes too short, and if I use 'output, it is parsed as 
> starting with family_type 256, which is not a member of the enum. Given 
> that the gnat documentation for the -xdr flag is literally two lines, I 
> don't really know where to look for more information on what I'm doing 
> wrong.

You never defined the protocol and implemented it in the first place. 
You used some code generation tools which, if ever worked, will bite you 
in the end.

To summarize the problem. The stream attribute 'Write writes the 
constrained object. 'Output adds the constraints. Ada is capable to have 
variable length records. C cannot do this. In short, it means that XDR's 
discriminated union can be mapped onto Ada's variant record with no 
default discriminant, but it cannot be directly mapped onto C's union. I 
presume that GNAT implements XDR correctly and the C side does not cope.

Which is one of thousand reasons not to implement a communication 
protocol by deriving representation from some language objects. Cutting 
corners will not help you.

Define the (application level [*]) protocol. Implement it in Ada. 
Implement it in C. Done.

---------------------
*  XDR or ASN.1 or whatever are not application level!

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: gnat -xdr flag confusion.
  2023-07-04 11:39 ` Dmitry A. Kazakov
@ 2023-07-06 17:32   ` magardner2010
  0 siblings, 0 replies; 3+ messages in thread
From: magardner2010 @ 2023-07-06 17:32 UTC (permalink / raw)


On 04/07/2023 14:39, Dmitry A. Kazakov wrote:
> On 2023-07-04 12:56, magardner2010 wrote:
> 
>> ...
> 
> You never defined the protocol and implemented it in the first place. 
> You used some code generation tools which, if ever worked, will bite you 
> in the end.

With regards to the code generation tool (which I'm assuming refers to 
chtGPT, for which I don't have enough creatively insulting backronyms), 
I spent a good half a day getting the output to actually be accepted by 
rpcgen. I then rewrote most of it from scratch.

With regards to the protocol implementation, I would like to point at 
the function that begins at 
https://github.com/smeagolthellama/szakdolgozat-notes/blob/f0b5143855f75354d41509845b0a41f0902d2928/ada/src/network_tree.adb#L29 
, which has successfully communicated with other instances of itself, 
albeit using 'write and 'read to handle anything more complicated than 
"is the first character of the message a '?', a 'j', or a '>'?". My 
question was about how to get C to understand the language Ada is 
talking to itself in, given that that language should be at least 
related to XDR.

> 
> To summarize the problem. The stream attribute 'Write writes the 
> constrained object. 'Output adds the constraints. Ada is capable to have 
> variable length records. C cannot do this. In short, it means that XDR's 
> discriminated union can be mapped onto Ada's variant record with no 
> default discriminant, but it cannot be directly mapped onto C's union. I 
> presume that GNAT implements XDR correctly and the C side does not cope.
> 

I'm not sure I understand what you're saying here. Given that rpcgen 
(which generates functions for xdr, as well as rpc, a superset thereof) 
was a part of GNU's libc for a while, and still is on some ubuntu boxes, 
along with the fact that a number of Linux's favourite protocols (such 
as NFS) are implemented using it, I don't think the issue is the C side 
implementing the encoder/decoder in a way that doesn't match my spec. I 
expect either an Ada issue, a spec issue, or both.

> Which is one of thousand reasons not to implement a communication 
> protocol by deriving representation from some language objects. Cutting 
> corners will not help you.

I suppose there is wisdom in that, especially when attempting to 
communicate across architectures, but I was working under the assumption 
that the -xdr flag would remove the issue, as XDR is an 
architecture-and-programming-language-agnostic data encoding/decoding 
standard (or whatever an RFC counts as).

> 
> Define the (application level [*]) protocol. Implement it in Ada. 
> Implement it in C. Done.
> 
> ---------------------
> *  XDR or ASN.1 or whatever are not application level!
> 

I wouldn't have called XDR a protocol in the first place, except as a 
simplification. I would like to use it as a *part* of my protocol, not 
dissimilar to how NFS does, or programs that use G*ogle's protobuf thingie.

Specifically, when a peer receives a query (in the form of a message 
starting with '?'), it should respond with a lump of data (current idea 
is the Child_Set type from my previous post, encoded in the XDR format, 
hence the difficulties) saying how many peers it has (in range 0..2), 
and who they are (address-port combinations, where address can be IPv4 
or 6), so that the querying party can find out if there is space for it 
on this peer, or if it should look elsewhere. There are a couple of edge 
cases, but this if you are curious you can look at my code.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-07-06 17:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-04 10:56 gnat -xdr flag confusion magardner2010
2023-07-04 11:39 ` Dmitry A. Kazakov
2023-07-06 17:32   ` magardner2010

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox