@@ -79,6 +79,8 @@ type operation struct {
79
79
buf syscall.WSABuf
80
80
msg windows.WSAMsg
81
81
sa syscall.Sockaddr
82
+ sa4 syscall.SockaddrInet4
83
+ sa6 syscall.SockaddrInet6
82
84
rsa * syscall.RawSockaddrAny
83
85
rsan int32
84
86
handle syscall.Handle
@@ -595,7 +597,30 @@ func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
595
597
596
598
// ReadFrom wraps the recvfrom network call for IPv4.
597
599
func (fd * FD ) ReadFromInet4 (buf []byte , sa4 * syscall.SockaddrInet4 ) (int , error ) {
598
- n , sa , err := fd .ReadFrom (buf )
600
+ if len (buf ) == 0 {
601
+ return 0 , nil
602
+ }
603
+ if len (buf ) > maxRW {
604
+ buf = buf [:maxRW ]
605
+ }
606
+ if err := fd .readLock (); err != nil {
607
+ return 0 , err
608
+ }
609
+ defer fd .readUnlock ()
610
+ o := & fd .rop
611
+ o .InitBuf (buf )
612
+ n , err := execIO (o , func (o * operation ) error {
613
+ if o .rsa == nil {
614
+ o .rsa = new (syscall.RawSockaddrAny )
615
+ }
616
+ o .rsan = int32 (unsafe .Sizeof (* o .rsa ))
617
+ return syscall .WSARecvFrom (o .fd .Sysfd , & o .buf , 1 , & o .qty , & o .flags , o .rsa , & o .rsan , & o .o , nil )
618
+ })
619
+ err = fd .eofError (n , err )
620
+ if err != nil {
621
+ return n , err
622
+ }
623
+ sa , _ := o .rsa .Sockaddr ()
599
624
if sa != nil {
600
625
* sa4 = * (sa .(* syscall.SockaddrInet4 ))
601
626
}
@@ -604,7 +629,30 @@ func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error)
604
629
605
630
// ReadFrom wraps the recvfrom network call for IPv6.
606
631
func (fd * FD ) ReadFromInet6 (buf []byte , sa6 * syscall.SockaddrInet6 ) (int , error ) {
607
- n , sa , err := fd .ReadFrom (buf )
632
+ if len (buf ) == 0 {
633
+ return 0 , nil
634
+ }
635
+ if len (buf ) > maxRW {
636
+ buf = buf [:maxRW ]
637
+ }
638
+ if err := fd .readLock (); err != nil {
639
+ return 0 , err
640
+ }
641
+ defer fd .readUnlock ()
642
+ o := & fd .rop
643
+ o .InitBuf (buf )
644
+ n , err := execIO (o , func (o * operation ) error {
645
+ if o .rsa == nil {
646
+ o .rsa = new (syscall.RawSockaddrAny )
647
+ }
648
+ o .rsan = int32 (unsafe .Sizeof (* o .rsa ))
649
+ return syscall .WSARecvFrom (o .fd .Sysfd , & o .buf , 1 , & o .qty , & o .flags , o .rsa , & o .rsan , & o .o , nil )
650
+ })
651
+ err = fd .eofError (n , err )
652
+ if err != nil {
653
+ return n , err
654
+ }
655
+ sa , _ := o .rsa .Sockaddr ()
608
656
if sa != nil {
609
657
* sa6 = * (sa .(* syscall.SockaddrInet6 ))
610
658
}
@@ -810,8 +858,42 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
810
858
}
811
859
812
860
// WriteTo wraps the sendto network call for IPv4.
813
- func (fd * FD ) WriteToInet4 (buf []byte , sa syscall.SockaddrInet4 ) (int , error ) {
814
- return fd .WriteTo (buf , & sa )
861
+ func (fd * FD ) WriteToInet4 (buf []byte , sa4 syscall.SockaddrInet4 ) (int , error ) {
862
+ if err := fd .writeLock (); err != nil {
863
+ return 0 , err
864
+ }
865
+ defer fd .writeUnlock ()
866
+
867
+ if len (buf ) == 0 {
868
+ // handle zero-byte payload
869
+ o := & fd .wop
870
+ o .InitBuf (buf )
871
+ o .sa4 = sa4
872
+ n , err := execIO (o , func (o * operation ) error {
873
+ return syscall .WSASendtoInet4 (o .fd .Sysfd , & o .buf , 1 , & o .qty , 0 , o .sa4 , & o .o , nil )
874
+ })
875
+ return n , err
876
+ }
877
+
878
+ ntotal := 0
879
+ for len (buf ) > 0 {
880
+ b := buf
881
+ if len (b ) > maxRW {
882
+ b = b [:maxRW ]
883
+ }
884
+ o := & fd .wop
885
+ o .InitBuf (b )
886
+ o .sa4 = sa4
887
+ n , err := execIO (o , func (o * operation ) error {
888
+ return syscall .WSASendtoInet4 (o .fd .Sysfd , & o .buf , 1 , & o .qty , 0 , o .sa4 , & o .o , nil )
889
+ })
890
+ ntotal += int (n )
891
+ if err != nil {
892
+ return ntotal , err
893
+ }
894
+ buf = buf [n :]
895
+ }
896
+ return ntotal , nil
815
897
}
816
898
817
899
// WriteTo wraps the sendto network call for IPv6.
0 commit comments