Black Lives Matter. Support the Equal Justice Initiative.

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

Documentation: net/internal/socktest

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

View as plain text