µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
posix-io/socket.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2015-2023 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from https://opensource.org/licenses/mit/.
11 */
12
13#ifndef CMSIS_PLUS_POSIX_IO_SOCKET_H_
14#define CMSIS_PLUS_POSIX_IO_SOCKET_H_
15
16// ----------------------------------------------------------------------------
17
18#if defined(__cplusplus)
19
20// ----------------------------------------------------------------------------
21
22#if defined(OS_USE_OS_APP_CONFIG_H)
23#include <cmsis-plus/os-app-config.h>
24#endif
25
29
30#include <mutex>
31
32// ----------------------------------------------------------------------------
33
34#pragma GCC diagnostic push
35#if defined(__clang__)
36#pragma clang diagnostic ignored "-Wc++98-compat"
37#endif
38
39// ----------------------------------------------------------------------------
40
41namespace os
42{
43 namespace posix
44 {
45 // ------------------------------------------------------------------------
46
47 class socket;
48 class socket_impl;
49 class net_stack;
50
51 // ------------------------------------------------------------------------
57#pragma GCC diagnostic push
58#if defined(__clang__)
59#elif defined(__GNUC__)
60#pragma GCC diagnostic ignored "-Wsuggest-final-methods"
61#pragma GCC diagnostic ignored "-Wsuggest-final-types"
62#endif
63 class socket : public io
64 {
65 // ----------------------------------------------------------------------
71 public:
72
73 socket (socket_impl& impl, /* class */ net_stack& ns);
74
79 // The rule of five.
80 socket (const socket&) = delete;
81 socket (socket&&) = delete;
82 socket&
83 operator= (const socket&) = delete;
84 socket&
85 operator= (socket&&) = delete;
86
91 virtual
92 ~socket () override;
93
98 // ----------------------------------------------------------------------
104 public:
105
106 virtual /* class */ socket*
107 accept (/* struct */ sockaddr* address, socklen_t* address_len);
108
109 virtual int
110 bind (const /* struct */ sockaddr* address, socklen_t address_len);
111
112 virtual int
113 connect (const /* struct */ sockaddr* address, socklen_t address_len);
114
115 virtual int
116 getpeername (/* struct */ sockaddr* address, socklen_t* address_len);
117
118 virtual int
119 getsockname (/* struct */ sockaddr* address, socklen_t* address_len);
120
121 virtual int
122 getsockopt (int level, int option_name, void* option_value,
123 socklen_t* option_len);
124
125 virtual int
126 listen (int backlog);
127
128 virtual ssize_t
129 recv (void* buffer, size_t length, int flags);
130
131 virtual ssize_t
132 recvfrom (void* buffer, size_t length, int flags,
133 /* struct */ sockaddr* address, socklen_t* address_len);
134
135 virtual ssize_t
136 recvmsg (/* struct */ msghdr* message, int flags);
137
138 virtual ssize_t
139 send (const void* buffer, size_t length, int flags);
140
141 virtual ssize_t
142 sendmsg (const /* struct */ msghdr* message, int flags);
143
144 virtual ssize_t
145 sendto (const void* message, size_t length, int flags,
146 const /* struct */ sockaddr* dest_addr, socklen_t dest_len);
147
148 virtual int
149 setsockopt (int level, int option_name, const void* option_value,
150 socklen_t option_len);
151
152 virtual int
153 shutdown (int how);
154
155 virtual int
156 sockatmark (void);
157
158 // ----------------------------------------------------------------------
159 // Support functions.
160
161#pragma GCC diagnostic push
162#if defined(__clang__)
163#elif defined(__GNUC__)
164#pragma GCC diagnostic ignored "-Wredundant-tags"
165#endif
166
167 class net_stack*
168 net_stack (void);
169
170#pragma GCC diagnostic pop
171
173 impl (void) const;
174
179 // ----------------------------------------------------------------------
180 public:
181
186 // Intrusive node used to link this socket to the deferred
187 // deallocation list. Must be public.
188 utils::double_list_links deferred_links_;
189
194 // ----------------------------------------------------------------------
195 protected:
196
201 class net_stack* net_stack_;
202
207 };
208#pragma GCC diagnostic pop
209
210 // ========================================================================
211
212 class socket_impl : public io_impl
213 {
214 // ----------------------------------------------------------------------
215
220 friend class socket;
221
226 // ----------------------------------------------------------------------
232 public:
233
234 socket_impl (void);
235
240 // The rule of five.
241 socket_impl (const socket_impl&) = delete;
242 socket_impl (socket_impl&&) = delete;
244 operator= (const socket_impl&) = delete;
246 operator= (socket_impl&&) = delete;
247
252 virtual
253 ~socket_impl () override;
254
259 // ----------------------------------------------------------------------
265 public:
266
267 virtual /* class */ socket*
268 do_accept (/* struct */ sockaddr* address, socklen_t* address_len) = 0;
269
270 virtual int
271 do_bind (const /* struct */ sockaddr* address, socklen_t address_len) = 0;
272
273 virtual int
274 do_connect (const /* struct */ sockaddr* address, socklen_t address_len) = 0;
275
276 virtual int
277 do_getpeername (/* struct */ sockaddr* address, socklen_t* address_len) = 0;
278
279 virtual int
280 do_getsockname (/* struct */ sockaddr* address, socklen_t* address_len) = 0;
281
282 virtual int
283 do_getsockopt (int level, int option_name, void* option_value,
284 socklen_t* option_len) = 0;
285
286 virtual int
287 do_listen (int backlog) = 0;
288
289 virtual ssize_t
290 do_recv (void* buffer, size_t length, int flags) = 0;
291
292 virtual ssize_t
293 do_recvfrom (void* buffer, size_t length, int flags,
294 /* struct */ sockaddr* address, socklen_t* address_len) = 0;
295
296 virtual ssize_t
297 do_recvmsg (/* struct */ msghdr* message, int flags) = 0;
298
299 virtual ssize_t
300 do_send (const void* buffer, size_t length, int flags) = 0;
301
302 virtual ssize_t
303 do_sendmsg (const /* struct */ msghdr* message, int flags) = 0;
304
305 virtual ssize_t
306 do_sendto (const void* message, size_t length, int flags,
307 const /* struct */ sockaddr* dest_addr, socklen_t dest_len) = 0;
308
309 virtual int
310 do_setsockopt (int level, int option_name, const void* option_value,
311 socklen_t option_len) = 0;
312
313 virtual int
314 do_shutdown (int how) = 0;
315
316 virtual int
317 do_sockatmark (void) = 0;
318
322 };
323
324 // ========================================================================
325
326 template<typename T>
328 {
329 // --------------------------------------------------------------------
330
331 public:
332
333 using value_type = T;
334
335 // ---------------------------------------------------------------------
336
342 public:
343
345
350 // The rule of five.
354 operator= (const socket_implementable&) = delete;
356 operator= (socket_implementable&&) = delete;
357
362 virtual
364
369 // --------------------------------------------------------------------
375 public:
376
377 // Support functions.
378
380 impl (void) const;
381
386 // --------------------------------------------------------------------
387 protected:
388
393 value_type impl_instance_;
394
398 };
399
400 // ========================================================================
401
402 template<typename T, typename L>
403 class socket_lockable : public socket
404 {
405 // --------------------------------------------------------------------
406
407 public:
408
409 using value_type = T;
410 using lockable_type = L;
411
412 // --------------------------------------------------------------------
413
419 public:
420
421 socket_lockable (class net_stack& ns, lockable_type& locker);
422
427 // The rule of five.
428 socket_lockable (const socket_lockable&) = delete;
429 socket_lockable (socket_lockable&&) = delete;
431 operator= (const socket_lockable&) = delete;
433 operator= (socket_lockable&&) = delete;
434
439 virtual
441
446 // --------------------------------------------------------------------
452 public:
453
454 virtual int
455 close (void) override;
456
457 virtual class socket*
458 accept (/* struct */ sockaddr* address, socklen_t* address_len) override;
459
460 virtual int
461 bind (const /* struct */ sockaddr* address, socklen_t address_len) override;
462
463 virtual int
464 connect (const /* struct */ sockaddr* address, socklen_t address_len)
465 override;
466
467 virtual int
468 getpeername (/* struct */ sockaddr* address, socklen_t* address_len) override;
469
470 virtual int
471 getsockname (/* struct */ sockaddr* address, socklen_t* address_len) override;
472
473 virtual int
474 getsockopt (int level, int option_name, void* option_value,
475 socklen_t* option_len) override;
476
477 virtual int
478 listen (int backlog) override;
479
480 virtual ssize_t
481 recv (void* buffer, size_t length, int flags) override;
482
483 virtual ssize_t
484 recvfrom (void* buffer, size_t length, int flags,
485 /* struct */ sockaddr* address, socklen_t* address_len) override;
486
487 virtual ssize_t
488 recvmsg (/* struct */ msghdr* message, int flags) override;
489
490 virtual ssize_t
491 send (const void* buffer, size_t length, int flags) override;
492
493 virtual ssize_t
494 sendmsg (const /* struct */ msghdr* message, int flags) override;
495
496 virtual ssize_t
497 sendto (const void* message, size_t length, int flags,
498 const /* struct */ sockaddr* dest_addr, socklen_t dest_len) override;
499
500 virtual int
501 setsockopt (int level, int option_name, const void* option_value,
502 socklen_t option_len) override;
503
504 virtual int
505 shutdown (int how) override;
506
507 virtual int
508 sockatmark (void) override;
509
510 // --------------------------------------------------------------------
511 // Support functions.
512
514 impl (void) const;
515
520 // --------------------------------------------------------------------
521 protected:
522
527 value_type impl_instance_;
528
529 lockable_type& locker_;
530
534 };
535
536 // ==========================================================================
537 } /* namespace posix */
538} /* namespace os */
539
540// ===== Inline & template implementations ====================================
541
542namespace os
543{
544 namespace posix
545 {
546 // ========================================================================
547
548 inline net_stack*
550 {
551 return net_stack_;
552 }
553
554 inline socket_impl&
555 socket::impl (void) const
556 {
557 return static_cast<socket_impl&> (impl_);
558 }
559
560 // ========================================================================
561
562 template<typename T>
564 socket
565 { impl_instance_, ns }
566 {
567#if defined(OS_TRACE_POSIX_IO_SOCKET)
568 trace::printf ("socket_implementable::%s()=@%p\n", __func__, this);
569#endif
570 }
571
572 template<typename T>
574 {
575#if defined(OS_TRACE_POSIX_IO_SOCKET)
576 trace::printf ("socket_implementable::%s() @%p\n", __func__, this);
577#endif
578 }
579
580 template<typename T>
583 {
584 return static_cast<value_type&> (impl_);
585 }
586
587 // ========================================================================
588
589 template<typename T, typename L>
591 lockable_type& locker) :
592 socket
593 { impl_instance_, ns }, //
594 locker_ (locker)
595 {
596#if defined(OS_TRACE_POSIX_IO_SOCKET)
597 trace::printf ("socket_lockable::%s()=@%p\n", __func__, this);
598#endif
599 }
600
601 template<typename T, typename L>
603 {
604#if defined(OS_TRACE_POSIX_IO_SOCKET)
605 trace::printf ("socket_lockable::%s() @%p\n", __func__, this);
606#endif
607 }
608
609 // ------------------------------------------------------------------------
610
611 template<typename T, typename L>
612 int
614 {
615 std::lock_guard<L> lock
616 { locker_ };
617
618 return socket::close ();
619 }
620
621 template<typename T, typename L>
622 /* class */ socket*
624 socklen_t* address_len)
625 {
626 std::lock_guard<L> lock
627 { locker_ };
628
629 return socket::accept (address, address_len);
630 }
631
632 template<typename T, typename L>
633 int
634 socket_lockable<T, L>::bind (const /* struct */ sockaddr* address,
635 socklen_t address_len)
636 {
637 std::lock_guard<L> lock
638 { locker_ };
639
640 return socket::bind (address, address_len);
641 }
642
643 template<typename T, typename L>
644 int
645 socket_lockable<T, L>::connect (const /* struct */ sockaddr* address,
646 socklen_t address_len)
647 {
648 std::lock_guard<L> lock
649 { locker_ };
650
651 return socket::connect (address, address_len);
652 }
653
654 template<typename T, typename L>
655 int
657 socklen_t* address_len)
658 {
659 std::lock_guard<L> lock
660 { locker_ };
661
662 return socket::getpeername (address, address_len);
663 }
664
665 template<typename T, typename L>
666 int
668 socklen_t* address_len)
669 {
670 std::lock_guard<L> lock
671 { locker_ };
672
673 return socket::getsockname (address, address_len);
674 }
675
676 template<typename T, typename L>
677 int
678 socket_lockable<T, L>::getsockopt (int level, int option_name,
679 void* option_value,
680 socklen_t* option_len)
681 {
682 std::lock_guard<L> lock
683 { locker_ };
684
685 return socket::getsockopt (level, option_name, option_value, option_len);
686 }
687
688 template<typename T, typename L>
689 int
691 {
692 std::lock_guard<L> lock
693 { locker_ };
694
695 return socket::listen (backlog);
696 }
697
698 template<typename T, typename L>
699 ssize_t
700 socket_lockable<T, L>::recv (void* buffer, size_t length, int flags)
701 {
702 std::lock_guard<L> lock
703 { locker_ };
704
705 return socket::recv (buffer, length, flags);
706 }
707
708 template<typename T, typename L>
709 ssize_t
710 socket_lockable<T, L>::recvfrom (void* buffer, size_t length, int flags,
711 /* struct */ sockaddr* address,
712 socklen_t* address_len)
713 {
714 std::lock_guard<L> lock
715 { locker_ };
716
717 return socket::recvfrom (buffer, length, flags, address, address_len);
718 }
719
720 template<typename T, typename L>
721 ssize_t
722 socket_lockable<T, L>::recvmsg (/* struct */ msghdr* message, int flags)
723 {
724 std::lock_guard<L> lock
725 { locker_ };
726
727 return socket::recvmsg (message, flags);
728 }
729
730 template<typename T, typename L>
731 ssize_t
732 socket_lockable<T, L>::send (const void* buffer, size_t length, int flags)
733 {
734 std::lock_guard<L> lock
735 { locker_ };
736
737 return socket::send (buffer, length, flags);
738 }
739
740 template<typename T, typename L>
741 ssize_t
742 socket_lockable<T, L>::sendmsg (const /* struct */ msghdr* message, int flags)
743 {
744 std::lock_guard<L> lock
745 { locker_ };
746
747 return socket::sendmsg (message, flags);
748 }
749
750 template<typename T, typename L>
751 ssize_t
752 socket_lockable<T, L>::sendto (const void* message, size_t length,
753 int flags,
754 const /* struct */ sockaddr* dest_addr,
755 socklen_t dest_len)
756 {
757 std::lock_guard<L> lock
758 { locker_ };
759
760 return socket::sendto (message, length, flags, dest_addr, dest_len);
761 }
762
763 template<typename T, typename L>
764 int
765 socket_lockable<T, L>::setsockopt (int level, int option_name,
766 const void* option_value,
767 socklen_t option_len)
768 {
769 std::lock_guard<L> lock
770 { locker_ };
771
772 return socket::setsockopt (level, option_name, option_value, option_len);
773 }
774
775 template<typename T, typename L>
776 int
778 {
779 std::lock_guard<L> lock
780 { locker_ };
781
782 return socket::shutdown (how);
783 }
784
785 template<typename T, typename L>
786 int
788 {
789 std::lock_guard<L> lock
790 { locker_ };
791
792 return socket::sockatmark ();
793 }
794
795 template<typename T, typename L>
798 {
799 return static_cast<value_type&> (impl_);
800 }
801
802 // ==========================================================================
803 } /* namespace posix */
804} /* namespace os */
805
806#pragma GCC diagnostic pop
807
808// ----------------------------------------------------------------------------
809
810#endif /* __cplusplus */
811
812// ----------------------------------------------------------------------------
813
814#endif /* CMSIS_PLUS_POSIX_IO_SOCKET_H_ */
Base I/O class.
Definition io.h:87
virtual int close(void)
Definition io.cpp:165
Network stack class.
Definition net-stack.h:82
virtual int do_bind(const sockaddr *address, socklen_t address_len)=0
virtual int do_getpeername(sockaddr *address, socklen_t *address_len)=0
virtual int do_getsockopt(int level, int option_name, void *option_value, socklen_t *option_len)=0
virtual socket * do_accept(sockaddr *address, socklen_t *address_len)=0
virtual int do_listen(int backlog)=0
virtual ~socket_impl() override
Definition socket.cpp:223
virtual int do_setsockopt(int level, int option_name, const void *option_value, socklen_t option_len)=0
virtual ssize_t do_recvfrom(void *buffer, size_t length, int flags, sockaddr *address, socklen_t *address_len)=0
virtual ssize_t do_sendmsg(const msghdr *message, int flags)=0
virtual ssize_t do_recv(void *buffer, size_t length, int flags)=0
virtual ssize_t do_send(const void *buffer, size_t length, int flags)=0
virtual ssize_t do_sendto(const void *message, size_t length, int flags, const sockaddr *dest_addr, socklen_t dest_len)=0
virtual int do_getsockname(sockaddr *address, socklen_t *address_len)=0
virtual ssize_t do_recvmsg(msghdr *message, int flags)=0
virtual int do_connect(const sockaddr *address, socklen_t address_len)=0
virtual int do_sockatmark(void)=0
virtual int do_shutdown(int how)=0
value_type & impl(void) const
socket_implementable(class net_stack &ns)
virtual int sockatmark(void) override
virtual ssize_t send(const void *buffer, size_t length, int flags) override
virtual ssize_t recv(void *buffer, size_t length, int flags) override
virtual ssize_t sendmsg(const msghdr *message, int flags) override
virtual int setsockopt(int level, int option_name, const void *option_value, socklen_t option_len) override
virtual int listen(int backlog) override
virtual int close(void) override
virtual int shutdown(int how) override
virtual ssize_t sendto(const void *message, size_t length, int flags, const sockaddr *dest_addr, socklen_t dest_len) override
value_type & impl(void) const
virtual int getsockname(sockaddr *address, socklen_t *address_len) override
virtual ssize_t recvmsg(msghdr *message, int flags) override
virtual class socket * accept(sockaddr *address, socklen_t *address_len) override
socket_lockable(class net_stack &ns, lockable_type &locker)
virtual int bind(const sockaddr *address, socklen_t address_len) override
virtual ssize_t recvfrom(void *buffer, size_t length, int flags, sockaddr *address, socklen_t *address_len) override
virtual int connect(const sockaddr *address, socklen_t address_len) override
virtual int getpeername(sockaddr *address, socklen_t *address_len) override
virtual int getsockopt(int level, int option_name, void *option_value, socklen_t *option_len) override
Network socket.
virtual int setsockopt(int level, int option_name, const void *option_value, socklen_t option_len)
Definition socket.cpp:187
virtual int sockatmark(void)
Definition socket.cpp:207
virtual int listen(int backlog)
Definition socket.cpp:122
virtual int getsockname(sockaddr *address, socklen_t *address_len)
Definition socket.cpp:102
virtual socket * accept(sockaddr *address, socklen_t *address_len)
Definition socket.cpp:60
virtual int bind(const sockaddr *address, socklen_t address_len)
Definition socket.cpp:75
virtual ssize_t recv(void *buffer, size_t length, int flags)
Definition socket.cpp:131
virtual ssize_t sendto(const void *message, size_t length, int flags, const sockaddr *dest_addr, socklen_t dest_len)
Definition socket.cpp:177
virtual ssize_t send(const void *buffer, size_t length, int flags)
Definition socket.cpp:159
virtual int getpeername(sockaddr *address, socklen_t *address_len)
Definition socket.cpp:93
virtual ssize_t sendmsg(const msghdr *message, int flags)
Definition socket.cpp:168
virtual int connect(const sockaddr *address, socklen_t address_len)
Definition socket.cpp:84
virtual ssize_t recvfrom(void *buffer, size_t length, int flags, sockaddr *address, socklen_t *address_len)
Definition socket.cpp:140
virtual int shutdown(int how)
Definition socket.cpp:198
virtual ~socket() override
Definition socket.cpp:48
virtual ssize_t recvmsg(msghdr *message, int flags)
Definition socket.cpp:150
virtual int getsockopt(int level, int option_name, void *option_value, socklen_t *option_len)
Definition socket.cpp:111
socket_impl & impl(void) const
class net_stack * net_stack(void)
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:60
int socket(int domain, int type, int protocol)
System namespace.
uint32_t socklen_t