github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/net/internal/socktest/sys_windows.go (about)

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