Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for setting Out-Of-Band (OOB) data on packets #641

Open
RyanGordon opened this issue Jun 6, 2024 · 2 comments
Open

Support for setting Out-Of-Band (OOB) data on packets #641

RyanGordon opened this issue Jun 6, 2024 · 2 comments

Comments

@RyanGordon
Copy link

RyanGordon commented Jun 6, 2024

Summary

This feature request suggests adding a new function to the dtls package:

  • A Write() function that lets you set OOB data on the packet

Proposed format could be something like the following with an argument format similar to the UDPConn WriteMsgUDP function

(c *Conn) WriteWithOOB(b, oob []byte) (n, oobn int, err error)

This would be optionally available and accessible from the underlying Conn package

Example: Set the DSCP IP field on a linux based system

// Define the desired DSCP value. For example, 46 (EF class) for expedited forwarding.
// Shift it left by 2 bits to fit into the ToS field correctly.
dscpValue := byte(46 << 2)

// Create a single-byte slice with the DSCP value for the ToS field.
optionData := []byte{dscpValue}

// Update the Cmsghdr to set the Type of Service (ToS).
cmsgHeader := syscall.Cmsghdr{
    Level: unix.IPPROTO_IP, // IP level
    Type:  unix.IP_TOS,     // Type of Service
}

// Serialize the control message with the updated DiffServ value.
cmsg := SerializeCmsg(cmsgHeader, optionData)

// Print the serialized control message for debugging purposes.
fmt.Printf("%X\n", cmsg)

// The connection can write data to the desired address with the updated DiffServ header.
_, _, err = conn.WriteWithOOB([]byte("data"), cmsg)
if err != nil {
    log.Fatal(err)
}

func SerializeCmsg(h syscall.Cmsghdr, data []byte) []byte {
	cmsg := make([]byte, 0, unix.SizeofCmsghdr+len(data))
	cmsg = binary.LittleEndian.AppendUint64(cmsg, unix.SizeofCmsghdr+uint64(len(data)))
	cmsg = binary.LittleEndian.AppendUint32(cmsg, uint32(h.Level))
	cmsg = binary.LittleEndian.AppendUint32(cmsg, uint32(h.Type))
	return append(cmsg, data...)
}

Motivation

As a lower-level protocol library, this provides the ability to extensibly cover use cases that OOB can allow for, such as:

  • The ability to set the DiffServ IP header on a per-packet basis.
  • The ability to set the ECN bits on a per-packet basis. For instance, this is helpful to indicate congestion to the peer.

OOB as a general function allows us to make changes to the IP-header without having to construct the IP header ourselves.

Describe alternatives you've considered

It would be possible to implement specific DiffServ and ECN setting and getting helper functions on top of OOB, but limits the extensibility of providing an abstract OOB capability. This library is low-level enough that it should be possible to expose this lower-level extensibility without sacrificing the default and traditional net.Conn interface.

Additional context

Conn.Write

Below is the current flow for Conn.Write:

Conn.Write
  -> Conn.writePackets
    -> Conn.WriteToContext
      -> pion/transport/v3/netctx.PacketConn.WriteToContext
        -> net.WriteTo

Below is a potential proposed flow for Conn.WriteWithOOB

Conn.WriteWithOOB(pkt, oob)
  -> Conn.writePackets(ctx, []{pkt}, oob)
    -> pion/transport/v3/netctx.PacketConn.WriteToContext(ctx, compactedRawPacket, addr) <-- oob is added to ctx
     -> net.WriteMsgUDP <-- used if oob key is set in ctx
     -> net.WriteTo <- used if oob key is not set in ctx (default)

Here is an example implementation: https://github.com/pion/dtls/compare/ryang/conn_write_with_oob

@RyanGordon RyanGordon changed the title Support for setting and getting Out-Of-Band (OOB) data on packets Support for setting Out-Of-Band (OOB) data on packets Jun 6, 2024
@Sean-Der
Copy link
Member

Hey @RyanGordon I released v3.0.0!

Want to start landing this?

@Sean-Der
Copy link
Member

Sean-Der commented Nov 4, 2024

@RyanGordon did you find another way to solve this? Should I resolve?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants