github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/net/ipv4/control_unix.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
     6  // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
     7  
     8  package ipv4
     9  
    10  import (
    11  	"unsafe"
    12  
    13  	"github.com/hxx258456/ccgo/net/internal/iana"
    14  	"github.com/hxx258456/ccgo/net/internal/socket"
    15  
    16  	"golang.org/x/sys/unix"
    17  )
    18  
    19  func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
    20  	opt.Lock()
    21  	defer opt.Unlock()
    22  	if so, ok := sockOpts[ssoReceiveTTL]; ok && cf&FlagTTL != 0 {
    23  		if err := so.SetInt(c, boolint(on)); err != nil {
    24  			return err
    25  		}
    26  		if on {
    27  			opt.set(FlagTTL)
    28  		} else {
    29  			opt.clear(FlagTTL)
    30  		}
    31  	}
    32  	if so, ok := sockOpts[ssoPacketInfo]; ok {
    33  		if cf&(FlagSrc|FlagDst|FlagInterface) != 0 {
    34  			if err := so.SetInt(c, boolint(on)); err != nil {
    35  				return err
    36  			}
    37  			if on {
    38  				opt.set(cf & (FlagSrc | FlagDst | FlagInterface))
    39  			} else {
    40  				opt.clear(cf & (FlagSrc | FlagDst | FlagInterface))
    41  			}
    42  		}
    43  	} else {
    44  		if so, ok := sockOpts[ssoReceiveDst]; ok && cf&FlagDst != 0 {
    45  			if err := so.SetInt(c, boolint(on)); err != nil {
    46  				return err
    47  			}
    48  			if on {
    49  				opt.set(FlagDst)
    50  			} else {
    51  				opt.clear(FlagDst)
    52  			}
    53  		}
    54  		if so, ok := sockOpts[ssoReceiveInterface]; ok && cf&FlagInterface != 0 {
    55  			if err := so.SetInt(c, boolint(on)); err != nil {
    56  				return err
    57  			}
    58  			if on {
    59  				opt.set(FlagInterface)
    60  			} else {
    61  				opt.clear(FlagInterface)
    62  			}
    63  		}
    64  	}
    65  	return nil
    66  }
    67  
    68  func marshalTTL(b []byte, cm *ControlMessage) []byte {
    69  	m := socket.ControlMessage(b)
    70  	m.MarshalHeader(iana.ProtocolIP, unix.IP_RECVTTL, 1)
    71  	return m.Next(1)
    72  }
    73  
    74  func parseTTL(cm *ControlMessage, b []byte) {
    75  	cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0])))
    76  }