...

Source file src/pkg/net/internal/socktest/sys_unix.go

     1	// Copyright 2015 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 js,wasm linux nacl netbsd openbsd solaris
     6	
     7	package socktest
     8	
     9	import "syscall"
    10	
    11	// Socket wraps syscall.Socket.
    12	func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) {
    13		sw.once.Do(sw.init)
    14	
    15		so := &Status{Cookie: cookie(family, sotype, proto)}
    16		sw.fmu.RLock()
    17		f := sw.fltab[FilterSocket]
    18		sw.fmu.RUnlock()
    19	
    20		af, err := f.apply(so)
    21		if err != nil {
    22			return -1, err
    23		}
    24		s, so.Err = syscall.Socket(family, sotype, proto)
    25		if err = af.apply(so); err != nil {
    26			if so.Err == nil {
    27				syscall.Close(s)
    28			}
    29			return -1, err
    30		}
    31	
    32		sw.smu.Lock()
    33		defer sw.smu.Unlock()
    34		if so.Err != nil {
    35			sw.stats.getLocked(so.Cookie).OpenFailed++
    36			return -1, so.Err
    37		}
    38		nso := sw.addLocked(s, family, sotype, proto)
    39		sw.stats.getLocked(nso.Cookie).Opened++
    40		return s, nil
    41	}
    42	
    43	// Close wraps syscall.Close.
    44	func (sw *Switch) Close(s int) (err error) {
    45		so := sw.sockso(s)
    46		if so == nil {
    47			return syscall.Close(s)
    48		}
    49		sw.fmu.RLock()
    50		f := sw.fltab[FilterClose]
    51		sw.fmu.RUnlock()
    52	
    53		af, err := f.apply(so)
    54		if err != nil {
    55			return err
    56		}
    57		so.Err = syscall.Close(s)
    58		if err = af.apply(so); err != nil {
    59			return err
    60		}
    61	
    62		sw.smu.Lock()
    63		defer sw.smu.Unlock()
    64		if so.Err != nil {
    65			sw.stats.getLocked(so.Cookie).CloseFailed++
    66			return so.Err
    67		}
    68		delete(sw.sotab, s)
    69		sw.stats.getLocked(so.Cookie).Closed++
    70		return nil
    71	}
    72	
    73	// Connect wraps syscall.Connect.
    74	func (sw *Switch) Connect(s int, sa syscall.Sockaddr) (err error) {
    75		so := sw.sockso(s)
    76		if so == nil {
    77			return syscall.Connect(s, sa)
    78		}
    79		sw.fmu.RLock()
    80		f := sw.fltab[FilterConnect]
    81		sw.fmu.RUnlock()
    82	
    83		af, err := f.apply(so)
    84		if err != nil {
    85			return err
    86		}
    87		so.Err = syscall.Connect(s, sa)
    88		if err = af.apply(so); err != nil {
    89			return err
    90		}
    91	
    92		sw.smu.Lock()
    93		defer sw.smu.Unlock()
    94		if so.Err != nil {
    95			sw.stats.getLocked(so.Cookie).ConnectFailed++
    96			return so.Err
    97		}
    98		sw.stats.getLocked(so.Cookie).Connected++
    99		return nil
   100	}
   101	
   102	// Listen wraps syscall.Listen.
   103	func (sw *Switch) Listen(s, backlog int) (err error) {
   104		so := sw.sockso(s)
   105		if so == nil {
   106			return syscall.Listen(s, backlog)
   107		}
   108		sw.fmu.RLock()
   109		f := sw.fltab[FilterListen]
   110		sw.fmu.RUnlock()
   111	
   112		af, err := f.apply(so)
   113		if err != nil {
   114			return err
   115		}
   116		so.Err = syscall.Listen(s, backlog)
   117		if err = af.apply(so); err != nil {
   118			return err
   119		}
   120	
   121		sw.smu.Lock()
   122		defer sw.smu.Unlock()
   123		if so.Err != nil {
   124			sw.stats.getLocked(so.Cookie).ListenFailed++
   125			return so.Err
   126		}
   127		sw.stats.getLocked(so.Cookie).Listened++
   128		return nil
   129	}
   130	
   131	// Accept wraps syscall.Accept.
   132	func (sw *Switch) Accept(s int) (ns int, sa syscall.Sockaddr, err error) {
   133		so := sw.sockso(s)
   134		if so == nil {
   135			return syscall.Accept(s)
   136		}
   137		sw.fmu.RLock()
   138		f := sw.fltab[FilterAccept]
   139		sw.fmu.RUnlock()
   140	
   141		af, err := f.apply(so)
   142		if err != nil {
   143			return -1, nil, err
   144		}
   145		ns, sa, so.Err = syscall.Accept(s)
   146		if err = af.apply(so); err != nil {
   147			if so.Err == nil {
   148				syscall.Close(ns)
   149			}
   150			return -1, nil, err
   151		}
   152	
   153		sw.smu.Lock()
   154		defer sw.smu.Unlock()
   155		if so.Err != nil {
   156			sw.stats.getLocked(so.Cookie).AcceptFailed++
   157			return -1, nil, so.Err
   158		}
   159		nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
   160		sw.stats.getLocked(nso.Cookie).Accepted++
   161		return ns, sa, nil
   162	}
   163	
   164	// GetsockoptInt wraps syscall.GetsockoptInt.
   165	func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) {
   166		so := sw.sockso(s)
   167		if so == nil {
   168			return syscall.GetsockoptInt(s, level, opt)
   169		}
   170		sw.fmu.RLock()
   171		f := sw.fltab[FilterGetsockoptInt]
   172		sw.fmu.RUnlock()
   173	
   174		af, err := f.apply(so)
   175		if err != nil {
   176			return -1, err
   177		}
   178		soerr, so.Err = syscall.GetsockoptInt(s, level, opt)
   179		so.SocketErr = syscall.Errno(soerr)
   180		if err = af.apply(so); err != nil {
   181			return -1, err
   182		}
   183	
   184		if so.Err != nil {
   185			return -1, so.Err
   186		}
   187		if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) {
   188			sw.smu.Lock()
   189			sw.stats.getLocked(so.Cookie).Connected++
   190			sw.smu.Unlock()
   191		}
   192		return soerr, nil
   193	}
   194	

View as plain text