github.com/sagernet/wireguard-go@v0.0.0-20231215174105-89dec3b2f3e8/conn/mark_unix.go (about)

     1  //go:build linux || openbsd || freebsd
     2  
     3  /* SPDX-License-Identifier: MIT
     4   *
     5   * Copyright (C) 2017-2023 WireGuard LLC. All Rights Reserved.
     6   */
     7  
     8  package conn
     9  
    10  import (
    11  	"runtime"
    12  
    13  	"golang.org/x/sys/unix"
    14  )
    15  
    16  var fwmarkIoctl int
    17  
    18  func init() {
    19  	switch runtime.GOOS {
    20  	case "linux", "android":
    21  		fwmarkIoctl = 36 /* unix.SO_MARK */
    22  	case "freebsd":
    23  		fwmarkIoctl = 0x1015 /* unix.SO_USER_COOKIE */
    24  	case "openbsd":
    25  		fwmarkIoctl = 0x1021 /* unix.SO_RTABLE */
    26  	}
    27  }
    28  
    29  func (s *StdNetBind) SetMark(mark uint32) error {
    30  	var operr error
    31  	if fwmarkIoctl == 0 {
    32  		return nil
    33  	}
    34  	if s.ipv4 != nil {
    35  		fd, err := s.ipv4.SyscallConn()
    36  		if err != nil {
    37  			return err
    38  		}
    39  		err = fd.Control(func(fd uintptr) {
    40  			operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
    41  		})
    42  		if err == nil {
    43  			err = operr
    44  		}
    45  		if err != nil {
    46  			return err
    47  		}
    48  	}
    49  	if s.ipv6 != nil {
    50  		fd, err := s.ipv6.SyscallConn()
    51  		if err != nil {
    52  			return err
    53  		}
    54  		err = fd.Control(func(fd uintptr) {
    55  			operr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, fwmarkIoctl, int(mark))
    56  		})
    57  		if err == nil {
    58  			err = operr
    59  		}
    60  		if err != nil {
    61  			return err
    62  		}
    63  	}
    64  	return nil
    65  }