...

Source file src/pkg/net/sockopt_posix.go

     1	// Copyright 2009 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	// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
     6	
     7	package net
     8	
     9	import (
    10		"internal/bytealg"
    11		"runtime"
    12		"syscall"
    13	)
    14	
    15	// Boolean to int.
    16	func boolint(b bool) int {
    17		if b {
    18			return 1
    19		}
    20		return 0
    21	}
    22	
    23	func ipv4AddrToInterface(ip IP) (*Interface, error) {
    24		ift, err := Interfaces()
    25		if err != nil {
    26			return nil, err
    27		}
    28		for _, ifi := range ift {
    29			ifat, err := ifi.Addrs()
    30			if err != nil {
    31				return nil, err
    32			}
    33			for _, ifa := range ifat {
    34				switch v := ifa.(type) {
    35				case *IPAddr:
    36					if ip.Equal(v.IP) {
    37						return &ifi, nil
    38					}
    39				case *IPNet:
    40					if ip.Equal(v.IP) {
    41						return &ifi, nil
    42					}
    43				}
    44			}
    45		}
    46		if ip.Equal(IPv4zero) {
    47			return nil, nil
    48		}
    49		return nil, errNoSuchInterface
    50	}
    51	
    52	func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
    53		if ifi == nil {
    54			return IPv4zero, nil
    55		}
    56		ifat, err := ifi.Addrs()
    57		if err != nil {
    58			return nil, err
    59		}
    60		for _, ifa := range ifat {
    61			switch v := ifa.(type) {
    62			case *IPAddr:
    63				if v.IP.To4() != nil {
    64					return v.IP, nil
    65				}
    66			case *IPNet:
    67				if v.IP.To4() != nil {
    68					return v.IP, nil
    69				}
    70			}
    71		}
    72		return nil, errNoSuchInterface
    73	}
    74	
    75	func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
    76		if ifi == nil {
    77			return nil
    78		}
    79		ifat, err := ifi.Addrs()
    80		if err != nil {
    81			return err
    82		}
    83		for _, ifa := range ifat {
    84			switch v := ifa.(type) {
    85			case *IPAddr:
    86				if a := v.IP.To4(); a != nil {
    87					copy(mreq.Interface[:], a)
    88					goto done
    89				}
    90			case *IPNet:
    91				if a := v.IP.To4(); a != nil {
    92					copy(mreq.Interface[:], a)
    93					goto done
    94				}
    95			}
    96		}
    97	done:
    98		if bytealg.Equal(mreq.Multiaddr[:], IPv4zero.To4()) {
    99			return errNoSuchMulticastInterface
   100		}
   101		return nil
   102	}
   103	
   104	func setReadBuffer(fd *netFD, bytes int) error {
   105		err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
   106		runtime.KeepAlive(fd)
   107		return wrapSyscallError("setsockopt", err)
   108	}
   109	
   110	func setWriteBuffer(fd *netFD, bytes int) error {
   111		err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
   112		runtime.KeepAlive(fd)
   113		return wrapSyscallError("setsockopt", err)
   114	}
   115	
   116	func setKeepAlive(fd *netFD, keepalive bool) error {
   117		err := fd.pfd.SetsockoptInt(syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))
   118		runtime.KeepAlive(fd)
   119		return wrapSyscallError("setsockopt", err)
   120	}
   121	
   122	func setLinger(fd *netFD, sec int) error {
   123		var l syscall.Linger
   124		if sec >= 0 {
   125			l.Onoff = 1
   126			l.Linger = int32(sec)
   127		} else {
   128			l.Onoff = 0
   129			l.Linger = 0
   130		}
   131		err := fd.pfd.SetsockoptLinger(syscall.SOL_SOCKET, syscall.SO_LINGER, &l)
   132		runtime.KeepAlive(fd)
   133		return wrapSyscallError("setsockopt", err)
   134	}
   135	

View as plain text