src/pkg/net/sockopt.go - The Go Programming Language

Golang

Source file src/pkg/net/sockopt.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 darwin freebsd linux netbsd openbsd windows
     6	
     7	// Socket options
     8	
     9	package net
    10	
    11	import (
    12		"os"
    13		"syscall"
    14		"time"
    15	)
    16	
    17	// Boolean to int.
    18	func boolint(b bool) int {
    19		if b {
    20			return 1
    21		}
    22		return 0
    23	}
    24	
    25	func ipv4AddrToInterface(ip IP) (*Interface, error) {
    26		ift, err := Interfaces()
    27		if err != nil {
    28			return nil, err
    29		}
    30		for _, ifi := range ift {
    31			ifat, err := ifi.Addrs()
    32			if err != nil {
    33				return nil, err
    34			}
    35			for _, ifa := range ifat {
    36				switch v := ifa.(type) {
    37				case *IPAddr:
    38					if ip.Equal(v.IP) {
    39						return &ifi, nil
    40					}
    41				case *IPNet:
    42					if ip.Equal(v.IP) {
    43						return &ifi, nil
    44					}
    45				}
    46			}
    47		}
    48		if ip.Equal(IPv4zero) {
    49			return nil, nil
    50		}
    51		return nil, errNoSuchInterface
    52	}
    53	
    54	func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
    55		if ifi == nil {
    56			return IPv4zero, nil
    57		}
    58		ifat, err := ifi.Addrs()
    59		if err != nil {
    60			return nil, err
    61		}
    62		for _, ifa := range ifat {
    63			switch v := ifa.(type) {
    64			case *IPAddr:
    65				if v.IP.To4() != nil {
    66					return v.IP, nil
    67				}
    68			case *IPNet:
    69				if v.IP.To4() != nil {
    70					return v.IP, nil
    71				}
    72			}
    73		}
    74		return nil, errNoSuchInterface
    75	}
    76	
    77	func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
    78		if ifi == nil {
    79			return nil
    80		}
    81		ifat, err := ifi.Addrs()
    82		if err != nil {
    83			return err
    84		}
    85		for _, ifa := range ifat {
    86			switch v := ifa.(type) {
    87			case *IPAddr:
    88				if a := v.IP.To4(); a != nil {
    89					copy(mreq.Interface[:], a)
    90					goto done
    91				}
    92			case *IPNet:
    93				if a := v.IP.To4(); a != nil {
    94					copy(mreq.Interface[:], a)
    95					goto done
    96				}
    97			}
    98		}
    99	done:
   100		if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
   101			return errNoSuchMulticastInterface
   102		}
   103		return nil
   104	}
   105	
   106	func setReadBuffer(fd *netFD, bytes int) error {
   107		if err := fd.incref(false); err != nil {
   108			return err
   109		}
   110		defer fd.decref()
   111		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes))
   112	}
   113	
   114	func setWriteBuffer(fd *netFD, bytes int) error {
   115		if err := fd.incref(false); err != nil {
   116			return err
   117		}
   118		defer fd.decref()
   119		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes))
   120	}
   121	
   122	func setReadDeadline(fd *netFD, t time.Time) error {
   123		if t.IsZero() {
   124			fd.rdeadline = 0
   125		} else {
   126			fd.rdeadline = t.UnixNano()
   127		}
   128		return nil
   129	}
   130	
   131	func setWriteDeadline(fd *netFD, t time.Time) error {
   132		if t.IsZero() {
   133			fd.wdeadline = 0
   134		} else {
   135			fd.wdeadline = t.UnixNano()
   136		}
   137		return nil
   138	}
   139	
   140	func setDeadline(fd *netFD, t time.Time) error {
   141		if err := setReadDeadline(fd, t); err != nil {
   142			return err
   143		}
   144		return setWriteDeadline(fd, t)
   145	}
   146	
   147	func setReuseAddr(fd *netFD, reuse bool) error {
   148		if err := fd.incref(false); err != nil {
   149			return err
   150		}
   151		defer fd.decref()
   152		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse)))
   153	}
   154	
   155	func setDontRoute(fd *netFD, dontroute bool) error {
   156		if err := fd.incref(false); err != nil {
   157			return err
   158		}
   159		defer fd.decref()
   160		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute)))
   161	}
   162	
   163	func setKeepAlive(fd *netFD, keepalive bool) error {
   164		if err := fd.incref(false); err != nil {
   165			return err
   166		}
   167		defer fd.decref()
   168		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
   169	}
   170	
   171	func setNoDelay(fd *netFD, noDelay bool) error {
   172		if err := fd.incref(false); err != nil {
   173			return err
   174		}
   175		defer fd.decref()
   176		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
   177	}
   178	
   179	func setLinger(fd *netFD, sec int) error {
   180		var l syscall.Linger
   181		if sec >= 0 {
   182			l.Onoff = 1
   183			l.Linger = int32(sec)
   184		} else {
   185			l.Onoff = 0
   186			l.Linger = 0
   187		}
   188		if err := fd.incref(false); err != nil {
   189			return err
   190		}
   191		defer fd.decref()
   192		return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
   193	}