1// +build windows
2
3package quic
4
5import (
6	"errors"
7	"fmt"
8	"net"
9	"syscall"
10
11	"golang.org/x/sys/windows"
12)
13
14const IP_DONTFRAGMENT = 14
15
16func newConn(c OOBCapablePacketConn) (connection, error) {
17	rawConn, err := c.SyscallConn()
18	if err != nil {
19		return nil, fmt.Errorf("couldn't get syscall.RawConn: %w", err)
20	}
21	if err := rawConn.Control(func(fd uintptr) {
22		// This should succeed if the connection is a IPv4 or a dual-stack connection.
23		// It will fail for IPv6 connections.
24		// TODO: properly handle error.
25		_ = windows.SetsockoptInt(windows.Handle(fd), windows.IPPROTO_IP, IP_DONTFRAGMENT, 1)
26	}); err != nil {
27		return nil, err
28	}
29	return &basicConn{PacketConn: c}, nil
30}
31
32func inspectReadBuffer(c net.PacketConn) (int, error) {
33	conn, ok := c.(interface {
34		SyscallConn() (syscall.RawConn, error)
35	})
36	if !ok {
37		return 0, errors.New("doesn't have a SyscallConn")
38	}
39	rawConn, err := conn.SyscallConn()
40	if err != nil {
41		return 0, fmt.Errorf("couldn't get syscall.RawConn: %w", err)
42	}
43	var size int
44	var serr error
45	if err := rawConn.Control(func(fd uintptr) {
46		size, serr = windows.GetsockoptInt(windows.Handle(fd), windows.SOL_SOCKET, windows.SO_RCVBUF)
47	}); err != nil {
48		return 0, err
49	}
50	return size, serr
51}
52
53func (i *packetInfo) OOB() []byte { return nil }
54