dgr::doc::pod3::dgr(3)

πŸ“¦ version 3.2.1, in ubuntu jammy

✨ dgr β€” the Datagram Retransmission system library πŸ’…

okay bestie, you've landed on dgr::doc::pod3::dgr(3), aka the DGR library functions page, and honestly? it's giving "reliable UDP but make it ✨thoughtful✨". grab a strawberry drink, we're going in πŸ“


🌸 SYNOPSIS 🌸

#include "dgr.h"

[see description for available functions]

πŸ’– DESCRIPTION πŸ’–

so. the DGR library is an alternative implementation of a subset of LTP, meant to be used over UDP/IP out there on the Internet. and here's the tea: unlike ION's canonical LTP implementation, it comes with a congestion control mechanism that reads LTP block transmission failure as a sign of network congestion (not data corruption, bestie, that's the whole point) and reduces the data transmission rate in response. no cap.

because of that, DGR differs from a lot of reliable-UDP systems in two main ways:

  • it uses adaptive timeout interval computation techniques borrowed from TCP</c> to try to avoid introducing congestion into the network. 🧚
  • it borrows the concurrent-session model of transmission from LTP (and ultimately from CFDP), instead of waiting for one datagram to be acknowledged before sending the next one, to improve bandwidth utilization. main character bandwidth behavior, truly.
⚠️ at this time, DGR is interoperable with other implementations of LTP only when each block it receives is transmitted in a single LTP data segment encapsulated in a single UDP datagram. more complex LTP behavior may be implemented in the future. so like, don't get creative yet πŸ™ˆ

🌈 THE FUNCTIONS 🌈

🫢 int dgr_open(uvast ownEngineId, unsigned in clientSvcId, unsigned short ownPortNbr, unsigned int ownIpAddress, char *memmgrName, Dgr *dgr, DgrRC *rc)

establishes the application's access to DGR communication service. the classic "hi hello let me in" move.

  • ownEngineId β€” the sending LTP engine ID that will characterize segments issued by this DGR service access point. and listen: in order to prevent erroneous system behavior, never assign the same LTP engine ID to any two interoperating DGR SAPs. not me emphasizing this, the spec is. πŸ’€
  • clientSvcId β€” identifies the LTP client service that all LTP segments issued by this DGR service access point will be directed to.
  • ownPortNbr β€” the port number to use for DGR service. if it's zero, a system-assigned UDP port number gets used instead. slay, let the system decide.
  • ownIpAddress β€” the Internet address of the network interface to use for DGR service. if zero, this argument defaults to the address of the interface identified by the local machine's host name.
  • memmgrName β€” the name of the memory manager (peep memmgr(3)) to use for dynamic memory management in DGR. if NULL, it defaults to the standard system malloc() and free() functions. the humble default, iconic.
  • dgr β€” the location where the service access pointer gets stored; you must hand this back on subsequent DGR function invocations.
  • rc β€” the location where the DGR return code from the attempt to open this service access point gets stored (it's always DgrOpened).

on any failure, returns -1. on success, returns zero. periodt.

πŸ¦‹ void dgr_getsockname(Dgr dgr, unsigned short *portNbr, unsigned int *ipAddress)

states the port number and IP address of the UDP socket used for this DGR service access point. it's giving "where am i, actually". πŸ‘‘

πŸŽ€ void dgr_close(Dgr dgr)

reverses dgr_open(), releasing resources where possible. the breakup arc. clean, mutual, no drama. πŸ’”βœ¨

πŸ”₯ int dgr_send(Dgr dgr, unsigned short toPortNbr, unsigned int toIpAddress, int notificationFlags, char *content, int length, DgrRC *rc)

sends the indicated content, of length as indicated, to the remote DGR service access point identified by toPortNbr and toIpAddress. the message will be retransmitted as necessary until either it is acknowledged or DGR determines that it cannot be delivered. it's persistent. it's committed. it's literally the moment.

  • notificationFlags β€” if non-zero, it's the logical OR of the notification behaviors requested for this datagram. the available behaviors are:
    • DGR_NOTE_FAILED β€” a notice of datagram delivery failure will be issued if delivery of the datagram fails.
    • DGR_NOTE_ACKED β€” a notice of datagram delivery success will be issued if delivery of the datagram succeeds.

notices are issued via dgr_receive() β€” that is, the thread that calls dgr_receive() on this DGR service access point will receive these notices interspersed with inbound datagram contents. yes bestie, interleaved. keep up πŸ’…

  • length β€” the length of content. it must be greater than zero and may be as great as 65535, but lengths greater than 8192 may not be supported by the local underlying UDP implementation; and to minimize the chance of data loss when transmitting over the internet, length should not exceed 512. so like, small is safe, bestie, this is not the time for a giant flex.
  • rc β€” the location where the DGR return code from the attempt to send the content gets stored.

on any failure, returns -1 and sets *rc to DgrFailed. on success, returns zero.

🧚 int dgr_receive(Dgr dgr, unsigned short *fromPortNbr, unsigned int *fromIpAddress, char *content, int *length, int *errnbr, int timeoutSeconds, DgrRC *rc)

delivers the oldest undelivered DGR event queued for delivery. first come first served, no cutting the line. 🎟️

DGR events come in two types: (a) messages received from a remote DGR service access point, and (b) notices about previously sent messages that DGR has determined either have been or cannot be delivered β€” as requested in the notificationFlags parameters you handed to the dgr_send() calls that sent those messages.

  • case (a), inbound message: dgr_receive() places the content of the inbound message in content, its length in length, and the IP address and port number of the sender in fromIpAddress and fromPortNbr. then it sets *rc to DgrDatagramReceived and returns zero. yay πŸ’–
  • case (b), delivery notice: dgr_receive() places the content of the affected outbound message in content and its length in length, and returns zero. if the event being reported is a delivery success, then DgrDatagramAcknowledged goes in *rc. otherwise, DgrDatagramNotAcknowledged goes in *rc and the relevant errno (if any) goes in *errnbr. 😭
🌸 the content buffer should be at least 65535 bytes in length to enable delivery of the content of the received or delivered/undeliverable message. don't skimp, bestie.

timeoutSeconds controls blocking behavior, and this is where the drama lives:

  • if timeoutSeconds is DGR_BLOCKING (i.e., -1), dgr_receive() will not return until (a) there's either an inbound message to deliver or an outbound message delivery result to report, or (b) the function is interrupted by means of dgr_interrupt().
  • if timeoutSeconds is DGR_POLL (i.e., zero), dgr_receive() returns immediately; if there's currently no inbound message to deliver and no outbound message delivery result to report, the function sets *rc to DgrTimedOut and returns zero. in and out, no waiting around.
  • for any other positive value of timeoutSeconds, dgr_receive() returns after the indicated number of seconds have lapsed (in which case the returned value of *rc is DgrTimedOut), or when there's a message to deliver or a delivery result to report, or when the function is interrupted by means of dgr_interrupt() β€” whichever occurs first.
  • when the function returns because of interruption by dgr_interrupt(), the value placed in *rc is DgrInterrupted instead of DgrDatagramReceived.
  • rc β€” the location where the DGR return code from the attempt to receive content gets stored.

on any I/O error or other unrecoverable system error, returns -1. otherwise it always returns zero, placing DgrFailed in *rc and writing a failure message in the event of an operating error.

πŸ’œ void dgr_interrupt(Dgr dgr)

interrupts a dgr_receive() invocation that is currently blocked. it's designed to be called from a signal handler; for that purpose, dgr may need to be obtained from a static variable. lowkey a little chaotic, but that's the assignment. 🌈


πŸ‘‘ SEE ALSO πŸ‘‘


okay that's the whole page bestie, you ate that 🫢 this was dgr::doc::pod3::dgr(3) β€” DGR library functions, brought to you by perl v5.24.1, dated 2016-07-07. and yes, the date is older than you, but the vibes are timeless βœ¨πŸ’… bye!!

πŸ“¦ where this page comes from