Source file src/net/internal/socktest/sys_windows.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  package socktest
     6  
     7  import (
     8  	"internal/syscall/windows"
     9  	"syscall"
    10  )
    11  
    12  // Socket wraps syscall.Socket.
    13  func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, 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 syscall.InvalidHandle, 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.Closesocket(s)
    29  		}
    30  		return syscall.InvalidHandle, 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 syscall.InvalidHandle, 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  // WSASocket wraps syscall.WSASocket.
    45  func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) {
    46  	sw.once.Do(sw.init)
    47  
    48  	so := &Status{Cookie: cookie(int(family), int(sotype), int(proto))}
    49  	sw.fmu.RLock()
    50  	f, _ := sw.fltab[FilterSocket]
    51  	sw.fmu.RUnlock()
    52  
    53  	af, err := f.apply(so)
    54  	if err != nil {
    55  		return syscall.InvalidHandle, err
    56  	}
    57  	s, so.Err = windows.WSASocket(family, sotype, proto, protinfo, group, flags)
    58  	if err = af.apply(so); err != nil {
    59  		if so.Err == nil {
    60  			syscall.Closesocket(s)
    61  		}
    62  		return syscall.InvalidHandle, err
    63  	}
    64  
    65  	sw.smu.Lock()
    66  	defer sw.smu.Unlock()
    67  	if so.Err != nil {
    68  		sw.stats.getLocked(so.Cookie).OpenFailed++
    69  		return syscall.InvalidHandle, so.Err
    70  	}
    71  	nso := sw.addLocked(s, int(family), int(sotype), int(proto))
    72  	sw.stats.getLocked(nso.Cookie).Opened++
    73  	return s, nil
    74  }
    75  
    76  // Closesocket wraps syscall.Closesocket.
    77  func (sw *Switch) Closesocket(s syscall.Handle) (err error) {
    78  	so := sw.sockso(s)
    79  	if so == nil {
    80  		return syscall.Closesocket(s)
    81  	}
    82  	sw.fmu.RLock()
    83  	f, _ := sw.fltab[FilterClose]
    84  	sw.fmu.RUnlock()
    85  
    86  	af, err := f.apply(so)
    87  	if err != nil {
    88  		return err
    89  	}
    90  	so.Err = syscall.Closesocket(s)
    91  	if err = af.apply(so); err != nil {
    92  		return err
    93  	}
    94  
    95  	sw.smu.Lock()
    96  	defer sw.smu.Unlock()
    97  	if so.Err != nil {
    98  		sw.stats.getLocked(so.Cookie).CloseFailed++
    99  		return so.Err
   100  	}
   101  	delete(sw.sotab, s)
   102  	sw.stats.getLocked(so.Cookie).Closed++
   103  	return nil
   104  }
   105  
   106  // Connect wraps syscall.Connect.
   107  func (sw *Switch) Connect(s syscall.Handle, sa syscall.Sockaddr) (err error) {
   108  	so := sw.sockso(s)
   109  	if so == nil {
   110  		return syscall.Connect(s, sa)
   111  	}
   112  	sw.fmu.RLock()
   113  	f, _ := sw.fltab[FilterConnect]
   114  	sw.fmu.RUnlock()
   115  
   116  	af, err := f.apply(so)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	so.Err = syscall.Connect(s, sa)
   121  	if err = af.apply(so); err != nil {
   122  		return err
   123  	}
   124  
   125  	sw.smu.Lock()
   126  	defer sw.smu.Unlock()
   127  	if so.Err != nil {
   128  		sw.stats.getLocked(so.Cookie).ConnectFailed++
   129  		return so.Err
   130  	}
   131  	sw.stats.getLocked(so.Cookie).Connected++
   132  	return nil
   133  }
   134  
   135  // ConnectEx wraps syscall.ConnectEx.
   136  func (sw *Switch) ConnectEx(s syscall.Handle, sa syscall.Sockaddr, b *byte, n uint32, nwr *uint32, o *syscall.Overlapped) (err error) {
   137  	so := sw.sockso(s)
   138  	if so == nil {
   139  		return syscall.ConnectEx(s, sa, b, n, nwr, o)
   140  	}
   141  	sw.fmu.RLock()
   142  	f, _ := sw.fltab[FilterConnect]
   143  	sw.fmu.RUnlock()
   144  
   145  	af, err := f.apply(so)
   146  	if err != nil {
   147  		return err
   148  	}
   149  	so.Err = syscall.ConnectEx(s, sa, b, n, nwr, o)
   150  	if err = af.apply(so); err != nil {
   151  		return err
   152  	}
   153  
   154  	sw.smu.Lock()
   155  	defer sw.smu.Unlock()
   156  	if so.Err != nil {
   157  		sw.stats.getLocked(so.Cookie).ConnectFailed++
   158  		return so.Err
   159  	}
   160  	sw.stats.getLocked(so.Cookie).Connected++
   161  	return nil
   162  }
   163  
   164  // Listen wraps syscall.Listen.
   165  func (sw *Switch) Listen(s syscall.Handle, backlog int) (err error) {
   166  	so := sw.sockso(s)
   167  	if so == nil {
   168  		return syscall.Listen(s, backlog)
   169  	}
   170  	sw.fmu.RLock()
   171  	f, _ := sw.fltab[FilterListen]
   172  	sw.fmu.RUnlock()
   173  
   174  	af, err := f.apply(so)
   175  	if err != nil {
   176  		return err
   177  	}
   178  	so.Err = syscall.Listen(s, backlog)
   179  	if err = af.apply(so); err != nil {
   180  		return err
   181  	}
   182  
   183  	sw.smu.Lock()
   184  	defer sw.smu.Unlock()
   185  	if so.Err != nil {
   186  		sw.stats.getLocked(so.Cookie).ListenFailed++
   187  		return so.Err
   188  	}
   189  	sw.stats.getLocked(so.Cookie).Listened++
   190  	return nil
   191  }
   192  
   193  // AcceptEx wraps syscall.AcceptEx.
   194  func (sw *Switch) AcceptEx(ls syscall.Handle, as syscall.Handle, b *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, rcvd *uint32, overlapped *syscall.Overlapped) error {
   195  	so := sw.sockso(ls)
   196  	if so == nil {
   197  		return syscall.AcceptEx(ls, as, b, rxdatalen, laddrlen, raddrlen, rcvd, overlapped)
   198  	}
   199  	sw.fmu.RLock()
   200  	f, _ := sw.fltab[FilterAccept]
   201  	sw.fmu.RUnlock()
   202  
   203  	af, err := f.apply(so)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	so.Err = syscall.AcceptEx(ls, as, b, rxdatalen, laddrlen, raddrlen, rcvd, overlapped)
   208  	if err = af.apply(so); err != nil {
   209  		return err
   210  	}
   211  
   212  	sw.smu.Lock()
   213  	defer sw.smu.Unlock()
   214  	if so.Err != nil {
   215  		sw.stats.getLocked(so.Cookie).AcceptFailed++
   216  		return so.Err
   217  	}
   218  	nso := sw.addLocked(as, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
   219  	sw.stats.getLocked(nso.Cookie).Accepted++
   220  	return nil
   221  }
   222  

View as plain text