On Fri, Mar 23, 2007 at 10:02:33AM +0000, Richard W.M. Jones wrote: > As you say, no appreciable difference in code side before and after the > change. > > It's interesting to note what SunRPC gives you over XDR (which you have > also noted in your emails): > > - serial numbers to correlate client requests and server responses (in > SunRPC these are called 'XID's) Unfortunately they crippled their use by only providing a single 'rm_xid' field. So the only way to do tracking is to mandate that the rm_xid of the method reply matches the rm_xid of the method call. This is why it is impossible to do asynchronous notifications from the server - ie let the server send you a message without any corresponding message having been received from the client. To do this correctly requires 2 independantly incremented sequences, one owned by the server & the other by the client. For method replies you need to have a completely separate field to indicate the serial number of the message you are replying to. I don't see any easy way to work around this limitation in SunRPC wire format :-( > - program numbers and versioning Not very different to replicate though - and in a less onerous way than SunRPC approach. It would seem that for every new version you need to provide a new set of all the marshalling methods defined by your program, even if you're only adding one new one. > - procedure numbers (same as your qemud_packet_{client,server} _data_type) > > In fact the header of the SunRPC request and reply is just an > XDR-encoded data structure looking like this: > > struct rpc_msg { > u_long rm_xid; // XID > // 0 = CALL, 1 = REPLY > enum msg_type rm_direction; > union { > struct call_body RM_cmb; > struct reply_body RM_rmb; > } ru; > }; > > struct call_body { > u_long cb_rpcvers; // always 2 > u_long cb_prog; // program number > u_long cb_vers; // program version > u_long cb_proc; // procedure number > struct opaque_auth cb_cred; // credentials - ignore > struct opaque_auth cb_verf; // verifier - ignore > }; > > struct reply_body is a bit more complex - see <rpc/rpc_msg.h>. > > Actually there are functions provided to generate the call and reply > headers (xdr_callhdr and xdr_replymsg) so we could use those directly to > create SunRPC-compatible headers. Advantages: Wire sniffing tools > which grok SunRPC will still work (Wireshark does NFS, so presumably it > does general Sun/ONC-RPC; Systemtap apparently supports it too). There > are various other efforts to run SunRPC over TLS (including an OCaml > one!) which we may still be able to interoperate with. Hmm, interesting point > In addition we have provided encryption and authentication. Your patch > punts on that - I understand why. Yep, that's a side issue for now - the existing code you've written could quite easily be ported over, since pretty much just have to replace the socket connection setup code & the read/write calls. So there's not really all that much to compare between the two impls. > About strings: char foo[MAX] (as you pointed out) could be replaced by > variable-length strings. There are at least three catches: (1) Who > owns/frees the strings? - I was never able to work that out. (2) NULL > is not supported directly, you have to use the option-looks-like- > a-pointer type (string *). (3) If the client and server don't trust > each other then you need to check the length of incoming strings > carefully to make sure that they aren't huge and potentially could cause > a DoS. In the XDR definition you can give a maximum size eg string foo<>; Allows an unlimited size string (MAX_INT32), while string foo<500>; Would ensure that the generated XDR routines will refuse a string larger than 500 bytes. The most compelling reason for string foo<500> instead of char foo[500] is that every array element is encoded on a 4 byte boundary, so your 1 byte chars end up taking 4 bytes each. The string datatype has a 4 byte length header, following by single bytes per character. A minor detail, but worth bearing in mind. > > > 1. Add an extra initial message type to do a major/minor version number > > exchange. Based on the negotiated versions, the server can activate > > or deactivate particular requests it allows from the client. > > > > 2. Add in the URI parsing routines to the qemud_interal.c driver, but > > only allow use of QEMU initially. > > > > 3. Add in the TLS + SSH client & server socket setup code to give an > > authenticated & secured remote channel > > > > 4. Re-factor qemud/dispatch.c so that it calls into the regular libvirt > > API for the Xen case, but keeps calling qemud/driver.c for the QEMU > > case. > > You'd definitely want to call it something other than 'qemu' ... Yes, the binary would obviously be renamed to just 'libvirtd', not that the user would really see the difference, becuase we already called the init script libvirtd to hide the details. Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|