diff --git a/src/common/protocol.h b/src/common/protocol.h --- a/src/common/protocol.h +++ b/src/common/protocol.h @@ -24,71 +24,161 @@ #include /** - Server types: + * Server types: + * + * It is assumed that any client has at least the functionality of a + * normal client (i.e., accepts all of the REQUIRED requests). These + * bitmask values add to the types of requests one may make to a + * server. After first connecting to a server or receiving a + * connection, a client shall send a DISTREN_REQUEST_VERSION packet + * describing its version. */ #define DISTREN_SERVERTYPE_SUBMIT (0x1) #define DISTREN_SERVERTYPE_DISTRIBUTE (0x2) #define DISTREN_SERVERTYPE_RENDER (0x4) +#define DISTREN_SERVERTYPE_CLIENT (0x8) /** - This file defines the constants and structs that the client uses to talk to the server and that the servers use to talk to eachother. + * This file defines the constants and structs that distren clients + * and server use to converse. */ + /** - generic, shared requests + * List of request types and metadata. */ enum distren_request_type { /** - identifies the version of software being - used by the sender and tells if it is a client or server. - Just send PACKAGE_STRING. + * identifies the version of software being used by the sender and + * tells if it is a client or server. Sends PACKAGE_STRING as well + * as informing the other server what type of server this is. + * + * DATA: struct distren_request followed by PACKAGE_STRING. The length of PACKAGE_STRING must be no longer than 32 bytes. + * + * REQUIRED: ALL */ DISTREN_REQUEST_VERSION = 1, + /** + * DATA: up to 32 bytes of a PING cookie + * + * REQUIRED: ALL + */ DISTREN_REQUEST_PING = 2, + /** + * DATA: up to 32 bytes copied from a received PING cookie + * + * REQUIRED: ALL + */ DISTREN_REQUEST_PONG = 3, /** - The data is the a reason describing why the one end is - disconnecting. The other end should respectfully close() - the socket or the sender will timeout shortly. + * The data is the a reason describing why the one end is + * disconnecting. The other end should respectfully close() + * the socket or the sender will timeout shortly. + * + * DATA: A string describing the reason for the connection's + * termination. + * + * REQUIRED: ALL */ DISTREN_REQUEST_DISCONNECT = 4, /** - client->server only requests - */ + * DATA: struct distren_request_submit + * + * REQUIRED: DISTREN_SERVERTYPE_SUBMIT + */ DISTREN_REQUEST_SUBMIT = 5, /** - anything->server requests + * Inform the other party about a job. + * + * DATA: struct distren_request_jobinfo + * + * REQUIRED: ALL */ - DISTREN_REQUEST_JOBINFO = 6, /*< retrieves information about a job based on its number */ + DISTREN_REQUEST_JOBINFO = 6, /** - server->anything + * Request a DISTREN_REQUEST_JOBINFO + * + * DATA: struct distren_request_jobinfo_get + * + * REQUIRED: DISTREN_SERVERTYPE_SUBMIT, DISTREN_SERVERTYPE_DISTRIBUTE */ - DISTREN_REQUEST_JOBINFO_RESPONSE = 7, /*< returns information about a job */ + DISTREN_REQUEST_JOBINFO_GET = 7, + + /** + * Command the other party to render a frame + * + * DATA: struct distren_request_frame_render + * + * REQUIRED: DISTREN_SERVERTYPE_RENDER + */ + DISTREN_REQUEST_FRAME_RENDER = 8, + /** + * Inform the receiver of the sender's state, such as frames being + * rendered or jobs that need to be completed. + * + * DATA: struct distren_request_status + * + * REQUIRED: DISTREN_SERVERTYPE_RENDER, DISTREN_SERVERTYPE_DISTRIBUTE, DISTREN_SERVERTYPE_CLIENT + */ + DISTREN_REQUEST_STATUS = 9, /** - server->server - */ - DISTREN_REQUEST_RENDERFRAME = 8, - DISTREN_REQUEST_DONEFRAME = 9, /* server should check to make sure the -slave is repoting on a frame it's actually assigned to */ - DISTREN_REQUEST_PROGRESS = 10, /*< tells another server of the progress of the first server's work at rendering */ - DISTREN_REQUEST_GETWORK = 11, - DISTREN_REQUEST_GETVERSION = 12, /*< returns version of software that slave should be running */ - DISTREN_REQUEST_GETRENDERPOWER = 13, /* returns the render power of a slave */ - DISTREN_REQUEST_SETRENDERPOWER = 14, /* sets renderpower in server -database */ + * Request that the receiver send a DISTREN_REQUEST_FRAME_STATUS + * packet. No data because the sending party might not beforehand + * know what frames/jobs the receiving server is managing. + * + * DATA: (none) + * + * REQUIRED: DISTREN_SERVERTYPE_RENDER + */ + DISTREN_REQUEST_STATUS_GET = 10, + /** - sets a frame back to unassigned, - happens if the slave quits for some reason. server code should only allow - resetting of a frame assigned to the slave calling the request (see php - code) - */ - DISTREN_REQUEST_RESETFRAME = 15, + * Allow a client to upload a job tarball over a remoteio line. A + * client that wants to do this must take care not to overbuffer + * his sendqueue so as to be able to respond to PING packets in + * time. A server receiving such a message will want to write the + * file as directly to disk as possible to avoid bagging a server + * down in swap. + * + * It is potential that if a server is DISTREN_SERVERTYPE_SUBMIT + * but not also DISTREN_SERVERTYPE_DISTRIBUTE, that this request + * would be relayed by the DISTREN_SERVERTYPE_SUBMIT server to a + * DISTREN_SERVERTYPE_DISTRIBUTE server so that other clients can + * obtain the file from the distribution server. In this case, the + * file's URL is already known. + * + * Of course, having this sort of functionality at all is where + * the nasty security issues start coming into play :-D. + * + * DATA: struct distren_request_file_post followed by a maximum of 131072 bytes (128kB). + * + * REQUIRED: DISTREN_SERVERTYPE_SUBMIT, DISTREN_SERVERTYPE_DISTRIBUTE + */ + DISTREN_REQUEST_FILE_POST = 11, + /** + * Request information about obtaining a file (such as a + * cURL-compatible URL) based on a distren file URL. + * + * DATA: struct distren_request_file_find + * + * REQUIRED: DISTREN_SERVERTYPE_DISTRIBUTE + */ + DISTREN_REQUEST_FILE_FIND = 12, + + /** + * Provide information about obtaining a file (such as a URL). + * + * DATA: struct distren_request_file + * + * REQUIRED: DISTREN_SERVERTYPE_DISTRIBUTE + */ + DISTREN_REQUEST_FILE = 13, }; struct distren_request @@ -101,6 +191,15 @@ struct distren_request }; /** + * A DISTREN_REQUEST_VERSION is started with a bitmask specification + * of the DISTREN_SERVERTYPE_* values. + */ +struct distren_request_version +{ + +}; + +/** * initializes and allocates request */ int distren_request_new(struct distren_request **req, uint32_t len, enum distren_request_type type); @@ -127,6 +226,29 @@ int distren_request_send(struct remoteio int distren_request_new_fromdata(struct distren_request **req, void *data, size_t len); /** + * Parses requests in a way suitable to be called from a + * remoteio_read_handle_func_t. + * + * If this function returns non-zero, you should handle the request + * and then call this function again (after shortening len and + * incrementing buf, of course). + * + * @param expectlen A pointer to a state variable that, if not NULL, can speed up this function. If you want to use this, you must set the variable to 0 before the first call and preserve the variable. + * @param buf the input buffer. + * @param len the length of buf. + * @param req a pointer to where we should set NULL if we don't have a full request or where we store the address of a newly allocated request. You should call distren_request_free() on this. + * @param req_data a pointer to where the request data pointer should be stored. This will just be set to a pointer in buf, so don't free() this. + * @param err this will be set to 0 if there is no error and to 1 if there is an error and the connection should be closed. You must check this. + * @return number of bytes that we have used from buf and that should be marked used. + */ +size_t distren_request_handle(size_t *expectlen, + void *buf, + size_t len, + struct distren_request **req, + void **req_data, + short *err); + +/** * frees request */ int distren_request_free(struct distren_request *req);