Implement FTP support over dmtcp: the dmftp library and the ftpd service - #1
Open
JohnAmadis wants to merge 1 commit into
Open
Implement FTP support over dmtcp: the dmftp library and the ftpd service#1JohnAmadis wants to merge 1 commit into
JohnAmadis wants to merge 1 commit into
Conversation
This repo now builds two modules. `dmftp` is a Library holding the protocol itself - an RFC 959 server and client sharing one control-line codec, one jail-safe path resolver and one transfer engine. `ftpd` is an Application that turns a unit file's args and an INI file into a running server. Only a Library can be enabled as another module's dependency, which is why the protocol does not live inside the service. Both PASV and PORT data connections work in both roles, TYPE A really translates line endings, and the server answers the full command set a real client needs (LIST/NLST, RETR/STOR/APPE, DELE/MKD/RMD, RNFR/RNTO, REST, ABOR, SIZE, FEAT, STAT). Files go through the dmod SAL rather than dmvfs - the same calls dmell's ls/cat/cp use, and the only option available, since dmvfs publishes no dmf-get package. Nothing here owns a thread. Outbound file data is pushed from dmtcp's on_writable callback, so a multi-megabyte RETR advances at exactly the rate the peer acknowledges data, with no timer and no polling loop. Two loader constraints shaped the code, both documented in app/dmftp/docs/dmftp.md: every dmtcp callback is registered from dmftp_net.c (the rule dmtcp's own docs record), and the command dispatch table holds no pointers at all - a pointer inside a static initialized aggregate is never relocated, which is why the verb is packed into a uint32_t and dispatch is a switch on an enum id. Tested: 34 steps for dmftp - the codec exhaustively, including malformed input a peer gets to choose, plus an end-to-end client session driven through the real dmnetbridge -> dmip -> dmtcp -> dmftp path - and 5 for ftpd's configuration contract. Requires dmtcp with on_writable/dmtcp_send_space(). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This repo now builds two modules.
dmftpis a Library holding the protocol itself - an RFC 959 server and client sharing one control-line codec, one jail-safe path resolver and one transfer engine.ftpdis an Application that turns a unit file's args and an INI file into a running server. Only a Library can be enabled as another module's dependency, which is why the protocol does not live inside the service.Both PASV and PORT data connections work in both roles, TYPE A really translates line endings, and the server answers the full command set a real client needs (LIST/NLST, RETR/STOR/APPE, DELE/MKD/RMD, RNFR/RNTO, REST, ABOR, SIZE, FEAT, STAT). Files go through the dmod SAL rather than dmvfs - the same calls dmell's ls/cat/cp use, and the only option available, since dmvfs publishes no dmf-get package.
Nothing here owns a thread. Outbound file data is pushed from dmtcp's on_writable callback, so a multi-megabyte RETR advances at exactly the rate the peer acknowledges data, with no timer and no polling loop.
Two loader constraints shaped the code, both documented in app/dmftp/docs/dmftp.md: every dmtcp callback is registered from dmftp_net.c (the rule dmtcp's own docs record), and the command dispatch table holds no pointers at all - a pointer inside a static initialized aggregate is never relocated, which is why the verb is packed into a uint32_t and dispatch is a switch on an enum id.
Tested: 34 steps for dmftp - the codec exhaustively, including malformed input a peer gets to choose, plus an end-to-end client session driven through the real dmnetbridge -> dmip -> dmtcp -> dmftp path - and 5 for ftpd's configuration contract.
Requires dmtcp with on_writable/dmtcp_send_space().