Giter Club home page Giter Club logo

rfc's Introduction

ZeroMQ RFC

This is the ZeroMQ RFC project.

We collect specifications for APIs, file formats, wire protocols, and processes.

The change process is C4: http://rfc.zeromq.org/spec:42 with a few modifications:

  • A specification is created and modified by pull requests according to C4.
  • Each specification has an editor who publishes the RFC to http://rfc.zeromq.org as needed.
  • Specification lifecycle SHOULD follow the lifecycle defined in COSS
  • Non-cosmetic changes are allowed only on Raw and Draft specifications.

rfc's People

Contributors

anarcat avatar anton-bot avatar bluca avatar c-rack avatar cbusbey avatar esc avatar ferdnyc avatar gummif avatar hintjens avatar hurtonm avatar ianbarber avatar jcoeltjen avatar jrossi avatar miniway avatar moshiba avatar nihlus avatar nodakai avatar paddor avatar pasternake avatar sappo avatar shishirpy avatar sigiesec avatar somdoron avatar stephan57160 avatar tomq42 avatar vvv avatar wambou avatar weex avatar wesyoung avatar yrashk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rfc's Issues

Revise Z85 base encoding spec to handle non-multiples of 4 bytes

The spec doesn't allow for arbitrary number of bytes, but it could be easily modified to handle it.

In fact, there is enough information in just the size parameter to determine encoding and decoding of non-multiple of 4s, and you wouldn't need to change the encoding dictionary at all.

In my implementation, I handle non-multiple of 4s at the end of the loop as follows:

Encode side:

...
  size_t leftover_bytes = ... \\ 3, 2 or 1
  if(leftover_bytes == 1) {
    uint32_t value = data[dbyte];
    encoded[ebyte] = base85_encoder_ring[value / 85UL % 85];
    encoded[ebyte+1] = base85_encoder_ring[value % 85];
  } else if(leftover_bytes == 2) {
    uint32_t value = 256UL*data[dbyte] + data[dbyte+1];
    encoded[ebyte] = base85_encoder_ring[value / 7225UL];
    encoded[ebyte+1] = base85_encoder_ring[value / 85UL % 85];
    encoded[ebyte+2] = base85_encoder_ring[value % 85];
  } else if(leftover_bytes == 3) {
    uint32_t value = 65536UL*data[dbyte] + 256UL*data[dbyte+1] + data[dbyte+2];
    encoded[ebyte] = base85_encoder_ring[value / 614125UL % 85];
    encoded[ebyte+1] = base85_encoder_ring[value / 7225UL % 85];
    encoded[ebyte+2] = base85_encoder_ring[value / 85UL % 85];
    encoded[ebyte+3] = base85_encoder_ring[value % 85];
  }
  return encoded;

Decode side:

  size_t leftover_bytes = ... \\ 4, 3 or 2
  if(leftover_bytes == 2) {
    base85_check_byte(data[ebyte]);
    base85_check_byte(data[ebyte+1]);
    uint32_t value = 85UL*base85_decoder_ring[data[ebyte]-32] + base85_decoder_ring[data[ebyte+1]-32];
    if(value > 256) throw std::runtime_error("base85_decode: corrupted input data, decoded block overflow");
    decoded[dbyte] = value;
  } else if(leftover_bytes == 3) {
    base85_check_byte(data[ebyte]);
    base85_check_byte(data[ebyte+1]);
    base85_check_byte(data[ebyte+2]);
    uint32_t value = 7225UL*base85_decoder_ring[data[ebyte]-32] + 85UL*base85_decoder_ring[data[ebyte+1]-32];
    value         += base85_decoder_ring[data[ebyte+2]-32];
    if(value > 65536) throw std::runtime_error("base85_decode: corrupted input data, decoded block overflow");
    decoded[dbyte] = value / 256UL;
    decoded[dbyte+1] = value % 256;
  } else if(leftover_bytes == 4) {
    base85_check_byte(data[ebyte]);
    base85_check_byte(data[ebyte+1]);
    base85_check_byte(data[ebyte+2]);
    base85_check_byte(data[ebyte+3]);
    uint32_t value = 614125UL*base85_decoder_ring[data[ebyte]-32] + 7225UL*base85_decoder_ring[data[ebyte+1]-32];
    value         += 85UL*base85_decoder_ring[data[ebyte+2]-32] + base85_decoder_ring[data[ebyte+3]-32];
    if(value > 16777216) throw std::runtime_error("base85_decode: corrupted input data, decoded block overflow");
    decoded[dbyte] = value / 65536UL;
    decoded[dbyte+1] = value / 256UL % 256;
    decoded[dbyte+2] = value % 256;
  }
  return decoded;

Problem: "master" branch is incompatible with Goal 1

42:C4 designates the latest in-progress branch as "master" here:

2.5. Branches and Releases

  1. The project SHALL have one branch (β€œmaster”) that always holds the latest in-progress version and SHOULD always build.
  2. The project SHALL NOT use topic branches for any reason. Personal forks MAY use topic branches.
  3. To make a stable release a Maintainer shall tag the repository. Stable releases SHALL always be released from the repository master.

While this was convention before, in 2020 "master" was identified at least across software development culture as incompatible with maximizing diversity of the community as described in 1. Goals:

  1. To maximize the scale and diversity of the community around a project, by reducing the friction for new Contributors and creating a scaled participation model with strong positive feedbacks;

C4: Administrator and Founder are not documented

in the "Preliminiaries" section, we define "Contributor" and "Maintainer", but not "Administrator" and "Founder" that are used in the last section.

I am not sure how to define those, but it seems to me those should be more clearly established earlier on.

Problem: recommended pattern for list iteration is broken

In RFC/21 CLASS the recommended pattern for list iteration is only <type> which cannot be valid. An commonly used approach in czmq is:

myp_mymod_t *mymod = myp_mymod_first (mymod);
while (mymod) {
    //  Do something
    mymod = myp_mymod_next (mymod);
}

36/ZRE seems to have errors

Hi,

Reading the ZRE RFC I noticed some discrepancy between the grammar and explanations for the WHISPER messages. This might be because of 20/ZRE version 1.

Explanation says:

The WHISPER command contains a single field, which is the message content defined as one 0MQ frame. ZRE does not support multi-frame message contents.

when the grammar says:

;     Send a multi-part message to a peer
whisper         = signature %d2 version sequence content
version         = number-1              ; Version number (3)
sequence        = number-2              ; Cyclic sequence number
content         = msg                   ; Wrapped message content

; A msg is zero or more distinct frames
msg             = *frame

So multi-frames messages are possible.

This error is also present in the version 3 43/ZRE.
If you agree, I can make the modification on it.

But should there be an errata for 36/ZRE ? Or just update it ?

37/ZMTP marked as 'raw' on the wiki

37/ZMTP is considered "draft" within the context of the specs and index, however the wiki page lists it as "raw".

I didn't want to attempt the change myself as I don't know which implementation exists which moved it out of raw and into draft.

Problem: invalid link in README.md

Seen in this README.md :

Specification lifecycle SHOULD follow the lifecycle defined in [COSS](http://rfc.unprotocols.org/spec:2/COSS)

The COSS link leads to "page not found".

Probem: XRAP cannot handle queries and custom meta data

I'm currently working on a REST (HTTP) to XRAP gateway which works fine up to a certain point. My first issue is with the query string. REST APIs usually use the query string to allow filtering, sorting, selecting and paging of collections. Currently those query parameters cannot be passed with the GET message. My idea is to extend the GET message with a hash that hold these parameters:

<message name = "GET" id = "3">
    <field name = "resource" type = "string">Schema/typename</field>
    <field name = "parameters" type = "hash">Filtering/sorting/selecting/paging</field>
    <field name = "if modified since" type = "number" size="8">GET if more recent</field>
    <field name = "if none match" type = "string">GET if changed</field>
    <field name = "content type" type = "string">Desired content type</field>
Retrieve a known resource.
</message>

The second issue is with custom metadata that one would attach to a GET_OK or GET_EMPTY. Those metadata may be the total size of a collection in case of paging, the API version or Hypermedia links (HATEOS). My idea is again to extend GET_OK message with a hash:

<message name = "GET OK" id = "4">
    <field name = "status code" type = "number" size = "2">Response status code 2xx</field>
    <field name = "content type" type = "string">Actual content type</field>
    <field name = "content body" type = "longstr">Resource specification</field>
    <field name = "metadata" type = "hash">Custom data:collection size/version/links</field>
Success response for GET.
</message>

These issues are possibly true for POST, PUT and DELETE as well but I currently don't have a use case to verify.

The third issue is regarding etags in GET_OK. A user might not be the creator or modifier of a resource and thus doesn't know the etag of this resource. Hence it would be helpful to pass the etag of a resource with GET_OK as well, so this client can use it as if none match for its next GET request.

Enhance modularity of the specifications

Currently, the specifications of the messaging patterns define how these should behave but the main ZMTP specification defines the commands used by those messaging patterns. We could enhance the modularity of the specifications by moving the definitions of the commands used by each messaging patterns in their own specification.

The ZMTP specification would define:

  • overall protocol (greeting, security handshake, and traffic = (command+))
  • framing of commands and messages
  • connection heartbeating

Each messaging pattern specification would define:

  • the behavior of the peers
  • the commands they use

This would allow to add new messaging patterns without having to modify the base ZMTP specification.

I am willing to make a PR to apply those changes.

C4 RFC uses non-inclusive language

Hi,

I wanted to use C4 as a reference for a personal project and had a look at the draft version.
The latest modifications on it are almost 2 year old and prior to GitHub change on its default branch name, abandoning "master" to use "main".

I think the RFC should be updated to take that into account, but leaving a note on "master" for historical projects.

FileMQ (RFC 35) cheezburger.sequence

In the grammar for the cheezburger command there are two fields: sequence and offset with the same exact explanation: "File offset in bytes".
In a command description sequence isn't even mentioned.

Is the sequence field redundant or does it just lacks description?
RFC 19 has the same problem.

Grammar:

; The server sends a file chunk
cheezburger = signature %d8 sequence operation filename offset eof headers chunk
sequence = number-8 ; File offset in bytes
operation = number-1 ; Create=%d1 delete=%d2
filename = string ; Relative name of file
offset = number-8 ; File offset in bytes
eof = number-1 ; Last chunk in file?
headers = dictionary ; File properties
chunk = chunk ; Data chunk

Command description

The CHEEZBURGER Command
The server SHALL send file content to the client using CHEEZBURGER commands. Each CHEEZBURGER command shall deliver a chunk of file data starting at a specific offset. The server MUST send the content of a single file as consecutive chunks and clients MAY depend on this behavior.

The headers field is reserved for future use.

ZMTP-PLAIN: prose contradicts ABNF

The prose contains this language:

All command bodies consist of an 8-character command name, padded with spaces, [...]

This contradicts the ABNF immediately prior, in which command names are of variable length and unpadded.

Libzmq's implementation conforms to the ABNF, so it's probably the prose that should be updated.

Problem: Public APIs only "should" be publicly documented, but for my project, I need this to be a requirement.

Problem: Kestrel project (independent of 0MQ; see http://kestrelcomputer.github.io/kestrel) demands that public APIs and other specifications be published in some form of documentation. C4 currently doesn't enforce this; instead, it only says that public standards "SHOULD" be documented. The Kestrel project would like to adopt the C4 process going forward, but would like to tailor this one feature, above anything else, to reflect the Kestrel Project values.

I started by forking the C4.1 process and tailoring it to the Kestrel project. After some discussions with Pieter Hintjens, we decided to contribute some of my tweaks back to the original RFC instead. Thus, I'm opening this issue as a means of detailing what the problem is (for me), and possibly to solicit feedback on the PR I will subsequently submit, in a way that is strictly compatible with the current C4.1 process.

RFC 43/ZYREv3: Undefined behaviour when shouting to a group the peer has not itself joined

During the process of writing a C++ implementation of RFC 43/ZYREv3, I've encountered a minor instance of undefined behaviour in the specification; namely, it is not defined whether or not a peer must first join a group in order to send a message to other peers participating in the group. The specification does not provide an affirmative or negative response to this question, leaving it up to the implementor's interpretation.

I can see valid use cases for both variants, but they also have their own drawbacks. I'm hoping that this issue can raise the topic, open discussions, and hopefully result in a clear answer being added to the specification.

Alternative 1 - A peer MAY join a group before sending messages to it

In this alternative, it is not a requirement that a peer joins a group before sending messages to it. Each peer does not need to filter messages after the fact if it only wishes to send messages and not receive them, and fewer network messages need to be transmitted (some of which almost assuredly would simply be dropped by send-only peers).

On the flip side, it may be unexpected or surprising behaviour to receive a shouted message from a node that is not part of the group. Some applications may rely on knowing the full set of nodes that participate in a group, be they uni- or bidirectional in the conversation.

Only minor alterations to the specification would be required in this alternative, as it is merely lacking clarifying language.

Alternative 2 - A peer MUST join a group before sending messages to it

In this alternative, it is an absolute requirement that a peer joins a group before sending messages to it, thereby broadcasting its intent to participate in it. As the specification is written today, no indication is given that this is the correct interpretation, but it is nevertheless an option. This interpretation would mean additional network messages may be sent to peers which have no actual interest in them, and moves the responsibility of filtering out unwanted messages into the application layer.

However, this also means that participation in a group is clearly and explicitly established by all participants, regardless of whether they wish to utilize uni- or bidirectional communication. Applications can rely on the fact that a message arriving via shout must also originate from a peer in one of the groups they participate in.

This would mean addition of more restrictive language to the specification, and other sections may need to be updated to reflect this. Should peers that attempt to send messages to groups they are not participating in be considered invalid and subsequently disconnected, for example?

Opinions

In my opinion, the correct interpretation of the specification as written is Alternative 1, and probably also the most versatile option. Applications can configure their participation with more granularity, and less network bandwidth is likely to be wasted on peers that do not wish to receive messages in the first place. I also think that an applications designed to rely on all potentially speaking peers in a group being known sounds like problems waiting to happen, but you never know - there may be appropriate use cases for this.

Problem: Netlify builds failing on UNSUPPORTED BUILD IMAGE

Builds for my PR earlier today and master once it was merged failed with the following message.

1:31:19 PM: ---------------------------------------------------------------------
  UNSUPPORTED BUILD IMAGE

  The build image for this site uses Ubuntu 16.04 Xenial Xerus, which is no longer supported.

  To enable builds for this site, select a later build image at the following link:
  https://app.netlify.com/sites/rfczeromq/settings/deploys#build-image-selection

  For more details, visit the build migration guide:
  https://answers.netlify.com/t/please-read-end-of-support-for-xenial-build-image-everything-you-need-to-know/68239
  ---------------------------------------------------------------------

Proposed solution:
Update to a later build image.

Remove any thread-safety arguments to the new messaging patterns

It seems that since #146, a lot of emphasis on thread-safety has been put into the specifications (37/ZMTP and the new messaging patterns. I don't understand why as I consider this to be an implementation detail.

I would argue that it is possible to make thread-safe implementations of existing messaging pattern, if, maybe, at a very small cost in performance (using lock-free data-structures).

I would propose to remove all the mentions of thread-safety reasons in all those specifications.

Architecture images not loaded

The RFC website does not display the images for any protocol. I have tried loading the page on Firefox, Edge and Safari. The images can be seen when you open the .md files in the repository but not on the website.

Problem: Inaccurate contribution instructions

The readme file for this repository claims the contribution process is per C4, however this is plainly not the case.

Pull request #196 was rejected despite C4 2.4.14 "Maintainers SHALL NOT make value judgments on correct patches."

In order to avoid misunderstandings it would be helpful to document the actual contribution rules so all potential contributors know what to expect.

Advertising a standard which is not actually followed helps no one.

License confusion (GPL vs. MPL [.... And others])

As a written work, ZMTP and other RFCs seem to be licensed under GPL, yet the reference implementation of ZMTP (libzmtp) is licensed under the slightly less restrictive MPL. This creates confusion. Namely, if one makes a modified version of ZMTP will it be required to release/share the changes in the form of a GPL covered upgrade to the ZMTP RFC or will the code itself be required to be licensed under GPL? This may seem like a silly issue, but in order to fully respect your works (and stay in line legally...), this needs to be clearer.

Problem: prefix makes git history look like a list of problems

I question the use of Problem: in the changelog summary. I believe it makes the commit history look like a list of bug instead of a list of solutions. It may be just semantic nitpicking but I prefer to see a summary of the solution in the summary, then details of the solution in the longer version of the commitlog. It seems to be a common standard as well: Linux, for example, mandates to "Describe the technical detail of the change(s) your patch includes." as opposed to the actual problem it resolves, which can still be refered to in the longer description. (source)

I understand where this is coming from, and maybe it's a good standard for an established project that is just fixing bugs, or that is used to that convention. But it is certainly surprising when coming from a more traditionnal background.

I would like to suggest turning that MUST into a SHOULD or MAY.

I agree, however, that a patch MUST adress an existing issue or known problem. It seems to me we already have something to that effect, however, earlier on (although it is "SHOULD be a minimal and accurate answer to exactly one identified and agreed problem" - maybe that should be a MUST?)

provide a summary of RFC 42:C4

I quite like the process described in the C4 RFC. I think it can be a useful tool to build and improve communities communications and operations.

However, I think the document is too heavy to read. Only because I was really interested in those issues did I decide to bite the bullet and actually read through it. It seems to me it is a rather big barrier to entry to make new contributors read that document as such, especially for people like testers, documenters or graphic artists which may not be so familiar with RFC-style technical documents.

I believe that an Abstract of the document would be a good improvement to the document. It is common for RFCs to have an Abstract and/or Introduction to explain the context and general outline of the process proposed. There is a Goals section, but it doesn't explicitely mention how those goals are accomplished.

Thank you for considering this idea.

Bump 37/ZMTP version to 4.0

The protocol specified in 37/ZMTP presents breaking changes in binary compatibility. (Subscribe/Unsubscribe messages versus Subscribe/Cancel commands.)

The protocol specifies version downgrading at the level of the major version (cf. the first three paragraphs of the version negociation.

Therefore, I believe the version of the protocol should be bumped to 4.0.

Licensing of protocol implementations (MDP, TSP, PPP, etc.)

Good day,

I am aware that a similar issue (#133) was answered in regards to actual library or language implementations, however it looks a little confusing when it comes to actual specific protocol implementations.

Case:
In our company, we want to use the Majordomo protocol which we will write our own implementation using the libzmq alongside following the specification defined on https://rfc.zeromq.org/spec/7 . The implementation will be used for "Software as a Service" product.

Issue:
The specification states, that the license of it (the specification, so presuming it goes the same for the protocol itself) is GPLv3.
When we look at https://github.com/zeromq/majordomo , which is an example guide reference implementation, it is licensed under MPL 2. There is a "sub implementation" in C (not C++), underneath the same project https://github.com/zeromq/majordomo/tree/master/libmdp which seems to be licensed under GPLv3. The example defined in the specification https://github.com/shykes/pyzmq-mdp is also licensed under GPLv3.

Now we understand that both ZeroMQ as well as any related projects are now slowly turning towards to be licensed under MPL 2 (ref: discussion on zeromq/majordomo#64 ).

The question is:
If we write our own implementation of Majordomo pattern (or any other pattern in this regard) how should we license it? Would we have the consent in this particular case to not license our implementation under GPLv3? Could you advise on how to best to approach this?

Many thanks

37/ZMTP 3.1 still in draft

Hi,

It seems that RFC 37/ZMTP defining the 3.1 version of the protocol is implemented in libzmq, should it be moved to Stable now ?

Maybe some other RFC are in use but not moved, like 42/C4.
Also, some deprecated RFC could be moved the same way.

Sorry, I am making lots of movement today πŸ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.