@@ -575,179 +575,25 @@ class FuzzedSock : public Sock
575
575
mutable std::optional<uint8_t > m_peek_data;
576
576
577
577
public:
578
- explicit FuzzedSock (FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider{fuzzed_data_provider}
579
- {
580
- m_socket = fuzzed_data_provider.ConsumeIntegralInRange <SOCKET>(INVALID_SOCKET - 1 , INVALID_SOCKET);
581
- }
578
+ explicit FuzzedSock (FuzzedDataProvider& fuzzed_data_provider);
582
579
583
- ~FuzzedSock () override
584
- {
585
- // Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
586
- // Sock::Reset() (not FuzzedSock::Reset()!) which will call CloseSocket(m_socket).
587
- // Avoid closing an arbitrary file descriptor (m_socket is just a random very high number which
588
- // theoretically may concide with a real opened file descriptor).
589
- Reset ();
590
- }
580
+ ~FuzzedSock () override ;
591
581
592
- FuzzedSock& operator =(Sock&& other) override
593
- {
594
- assert (false && " Move of Sock into FuzzedSock not allowed." );
595
- return *this ;
596
- }
582
+ FuzzedSock& operator =(Sock&& other) override ;
597
583
598
- void Reset () override
599
- {
600
- m_socket = INVALID_SOCKET;
601
- }
584
+ void Reset () override ;
602
585
603
- ssize_t Send (const void * data, size_t len, int flags) const override
604
- {
605
- constexpr std::array send_errnos{
606
- EACCES,
607
- EAGAIN,
608
- EALREADY,
609
- EBADF,
610
- ECONNRESET,
611
- EDESTADDRREQ,
612
- EFAULT,
613
- EINTR,
614
- EINVAL,
615
- EISCONN,
616
- EMSGSIZE,
617
- ENOBUFS,
618
- ENOMEM,
619
- ENOTCONN,
620
- ENOTSOCK,
621
- EOPNOTSUPP,
622
- EPIPE,
623
- EWOULDBLOCK,
624
- };
625
- if (m_fuzzed_data_provider.ConsumeBool ()) {
626
- return len;
627
- }
628
- const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange <ssize_t >(-1 , len);
629
- if (r == -1 ) {
630
- SetFuzzedErrNo (m_fuzzed_data_provider, send_errnos);
631
- }
632
- return r;
633
- }
586
+ ssize_t Send (const void * data, size_t len, int flags) const override ;
634
587
635
- ssize_t Recv (void * buf, size_t len, int flags) const override
636
- {
637
- // Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
638
- // SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
639
- // returning -1 and setting errno to EAGAIN repeatedly.
640
- constexpr std::array recv_errnos{
641
- ECONNREFUSED,
642
- EAGAIN,
643
- EBADF,
644
- EFAULT,
645
- EINTR,
646
- EINVAL,
647
- ENOMEM,
648
- ENOTCONN,
649
- ENOTSOCK,
650
- EWOULDBLOCK,
651
- };
652
- assert (buf != nullptr || len == 0 );
653
- if (len == 0 || m_fuzzed_data_provider.ConsumeBool ()) {
654
- const ssize_t r = m_fuzzed_data_provider.ConsumeBool () ? 0 : -1 ;
655
- if (r == -1 ) {
656
- SetFuzzedErrNo (m_fuzzed_data_provider, recv_errnos);
657
- }
658
- return r;
659
- }
660
- std::vector<uint8_t > random_bytes;
661
- bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool ()};
662
- if (m_peek_data.has_value ()) {
663
- // `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
664
- random_bytes.assign ({m_peek_data.value ()});
665
- if ((flags & MSG_PEEK) == 0 ) {
666
- m_peek_data.reset ();
667
- }
668
- pad_to_len_bytes = false ;
669
- } else if ((flags & MSG_PEEK) != 0 ) {
670
- // New call with `MSG_PEEK`.
671
- random_bytes = m_fuzzed_data_provider.ConsumeBytes <uint8_t >(1 );
672
- if (!random_bytes.empty ()) {
673
- m_peek_data = random_bytes[0 ];
674
- pad_to_len_bytes = false ;
675
- }
676
- } else {
677
- random_bytes = m_fuzzed_data_provider.ConsumeBytes <uint8_t >(
678
- m_fuzzed_data_provider.ConsumeIntegralInRange <size_t >(0 , len));
679
- }
680
- if (random_bytes.empty ()) {
681
- const ssize_t r = m_fuzzed_data_provider.ConsumeBool () ? 0 : -1 ;
682
- if (r == -1 ) {
683
- SetFuzzedErrNo (m_fuzzed_data_provider, recv_errnos);
684
- }
685
- return r;
686
- }
687
- std::memcpy (buf, random_bytes.data (), random_bytes.size ());
688
- if (pad_to_len_bytes) {
689
- if (len > random_bytes.size ()) {
690
- std::memset ((char *)buf + random_bytes.size (), 0 , len - random_bytes.size ());
691
- }
692
- return len;
693
- }
694
- if (m_fuzzed_data_provider.ConsumeBool () && std::getenv (" FUZZED_SOCKET_FAKE_LATENCY" ) != nullptr ) {
695
- std::this_thread::sleep_for (std::chrono::milliseconds{2 });
696
- }
697
- return random_bytes.size ();
698
- }
588
+ ssize_t Recv (void * buf, size_t len, int flags) const override ;
699
589
700
- int Connect (const sockaddr*, socklen_t ) const override
701
- {
702
- // Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
703
- // SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
704
- // returning -1 and setting errno to EAGAIN repeatedly.
705
- constexpr std::array connect_errnos{
706
- ECONNREFUSED,
707
- EAGAIN,
708
- ECONNRESET,
709
- EHOSTUNREACH,
710
- EINPROGRESS,
711
- EINTR,
712
- ENETUNREACH,
713
- ETIMEDOUT,
714
- };
715
- if (m_fuzzed_data_provider.ConsumeBool ()) {
716
- SetFuzzedErrNo (m_fuzzed_data_provider, connect_errnos);
717
- return -1 ;
718
- }
719
- return 0 ;
720
- }
590
+ int Connect (const sockaddr*, socklen_t ) const override ;
721
591
722
- int GetSockOpt (int level, int opt_name, void * opt_val, socklen_t * opt_len) const override
723
- {
724
- constexpr std::array getsockopt_errnos{
725
- ENOMEM,
726
- ENOBUFS,
727
- };
728
- if (m_fuzzed_data_provider.ConsumeBool ()) {
729
- SetFuzzedErrNo (m_fuzzed_data_provider, getsockopt_errnos);
730
- return -1 ;
731
- }
732
- if (opt_val == nullptr ) {
733
- return 0 ;
734
- }
735
- std::memcpy (opt_val,
736
- ConsumeFixedLengthByteVector (m_fuzzed_data_provider, *opt_len).data (),
737
- *opt_len);
738
- return 0 ;
739
- }
592
+ int GetSockOpt (int level, int opt_name, void * opt_val, socklen_t * opt_len) const override ;
740
593
741
594
bool Wait (std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr ) const override ;
742
595
743
- bool IsConnected (std::string& errmsg) const override
744
- {
745
- if (m_fuzzed_data_provider.ConsumeBool ()) {
746
- return true ;
747
- }
748
- errmsg = " disconnected at random by the fuzzer" ;
749
- return false ;
750
- }
596
+ bool IsConnected (std::string& errmsg) const override ;
751
597
};
752
598
753
599
[[nodiscard]] inline FuzzedSock ConsumeSock (FuzzedDataProvider& fuzzed_data_provider)
0 commit comments