URING++
Loading...
Searching...
No Matches
socket.h
1#pragma once
2
3#include <arpa/inet.h>
4#include <cassert>
5#include <memory>
6#include <netdb.h>
7#include <netinet/in.h>
8#include <stdexcept>
9#include <sys/socket.h>
10#include <unistd.h>
11#include <utility>
12
13#include "uringpp/awaitable.h"
14#include "uringpp/error.h"
15#include "uringpp/event_loop.h"
16#include "uringpp/pipe.h"
17#include "uringpp/task.h"
18
19#include "uringpp/detail/debug.h"
20#include "uringpp/detail/noncopyable.h"
21
22namespace uringpp {
23
24class file;
25class socket : public noncopyable {
26 std::shared_ptr<event_loop> loop_;
27 int fd_;
28 friend class listener;
29
30public:
36 int fd() const { return fd_; }
37
43 socket(socket &&other) noexcept
44 : loop_(std::move(other.loop_)), fd_(std::exchange(other.fd_, -1)) {
45 assert(fd_ != -1);
46 }
47
56 socket(std::shared_ptr<event_loop> loop, int domain, int type, int protocol)
57 : loop_(loop), fd_(::socket(domain, type, protocol)) {
58 check_errno(fd_, "failed to create socket");
59 }
60
67 socket(std::shared_ptr<event_loop> loop, int fd) : loop_(loop), fd_(fd) {
68 assert(fd_ > 0);
69 }
70
79 static task<socket> connect(std::shared_ptr<event_loop> loop,
80 std::string const &hostname,
81 std::string const &port) {
82 struct addrinfo hints, *servinfo, *p;
83 ::bzero(&hints, sizeof(hints));
84 hints.ai_family = AF_UNSPEC;
85 hints.ai_socktype = SOCK_STREAM;
86 if (auto rc =
87 ::getaddrinfo(hostname.c_str(), port.c_str(), &hints, &servinfo);
88 rc != 0) {
89 throw_with("failed to getaddrinfo: %s", ::gai_strerror(rc));
90 }
91 for (p = servinfo; p != nullptr; p = p->ai_next) {
92 int fd = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
93 if (fd <= 0) {
94 continue;
95 }
96 auto new_socket = socket(loop, fd);
97 int rc =
98 co_await loop->connect(new_socket.fd(), p->ai_addr, p->ai_addrlen);
99 if (rc == 0) {
100 ::freeaddrinfo(servinfo);
101 co_return new_socket;
102 }
103 }
104 ::freeaddrinfo(servinfo);
105 throw std::runtime_error("failed to connect");
106 }
107
114 if (fd_ > 0) {
115 loop_->close_detach(fd_);
116 }
117 }
118
125 if (fd_ > 0) {
126 co_await loop_->close(fd_);
127 fd_ = -1;
128 }
129 }
130
138 sqe_awaitable read(void *buf, size_t count) {
139 return loop_->read(fd_, buf, count, 0);
140 }
141
149 sqe_awaitable write(void const *buf, size_t count) {
150 return loop_->write(fd_, buf, count, 0);
151 }
152
160 sqe_awaitable readv(struct iovec const *iov, int iovcnt) {
161 return loop_->readv(fd_, iov, iovcnt);
162 }
163
171 sqe_awaitable writev(struct iovec const *iov, int iovcnt) {
172 return loop_->writev(fd_, iov, iovcnt, 0);
173 }
174
183 sqe_awaitable read_fixed(void *buf, size_t count, int buf_index) {
184 return loop_->read_fixed(fd_, buf, count, 0, buf_index);
185 }
186
195 sqe_awaitable write_fixed(void const *buf, size_t count, int buf_index) {
196 return loop_->write_fixed(fd_, buf, count, 0, buf_index);
197 }
198
206 sqe_awaitable sendmsg(struct msghdr const *msg, int flags = 0) {
207 return loop_->sendmsg(fd_, msg, flags);
208 }
209
217 sqe_awaitable recvmsg(struct msghdr *msg, int flags = 0) {
218 return loop_->recvmsg(fd_, msg, flags);
219 }
220
229 sqe_awaitable send(void const *buf, size_t len, int flags = 0) {
230 return loop_->send(fd_, buf, len, flags);
231 }
232
241 sqe_awaitable recv(void *buf, size_t len, int flags = 0) {
242 return loop_->recv(fd_, buf, len, flags);
243 }
244
251 sqe_awaitable shutdown(int how) { return loop_->shutdown(fd_, how); }
252
261 sqe_awaitable tee(file const &out, size_t count, unsigned int flags);
262
271 sqe_awaitable tee(socket const &out, size_t count, unsigned int flags) {
272 return loop_->tee(fd_, out.fd(), count, flags);
273 }
274
284 sqe_awaitable splice_to(pipe const &out, size_t nbytes, unsigned flags) {
285 return loop_->splice(fd_, 0, out.writable_fd(), 0, nbytes, flags);
286 }
287
296 sqe_awaitable splice_from(pipe const &in, size_t nbytes, unsigned flags) {
297 return loop_->splice(in.readable_fd(), 0, fd_, 0, nbytes, flags);
298 }
299};
300
301} // namespace uringpp
An opened file.
Definition: file.h:21
Definition: noncopyable.h:5
A pipe.
Definition: pipe.h:15
int writable_fd() const
Get the write end of the pipe.
Definition: pipe.h:56
int readable_fd() const
Get the read end of the pipe.
Definition: pipe.h:46
Definition: socket.h:25
sqe_awaitable readv(struct iovec const *iov, int iovcnt)
Vectorized read from the socket.
Definition: socket.h:160
sqe_awaitable sendmsg(struct msghdr const *msg, int flags=0)
Send messages to the socket.
Definition: socket.h:206
int fd() const
Get the file descriptor of the socket.
Definition: socket.h:36
sqe_awaitable recvmsg(struct msghdr *msg, int flags=0)
Receive messages from the socket.
Definition: socket.h:217
sqe_awaitable write_fixed(void const *buf, size_t count, int buf_index)
Write data from a preregistered buffer to the socket.
Definition: socket.h:195
sqe_awaitable read_fixed(void *buf, size_t count, int buf_index)
Read data to a preregistered buffer from the socket.
Definition: socket.h:183
sqe_awaitable recv(void *buf, size_t len, int flags=0)
Receive data from the socket.
Definition: socket.h:241
sqe_awaitable read(void *buf, size_t count)
Read data from the socket.
Definition: socket.h:138
socket(socket &&other) noexcept
Move construct a new socket object.
Definition: socket.h:43
~socket()
Destroy the socket object. If the socket is still open, it will be closed.
Definition: socket.h:113
task< void > close()
Close the socket.
Definition: socket.h:124
sqe_awaitable splice_to(pipe const &out, size_t nbytes, unsigned flags)
Splice the socket to a pipe.
Definition: socket.h:284
sqe_awaitable shutdown(int how)
Shutdown the socket.
Definition: socket.h:251
sqe_awaitable splice_from(pipe const &in, size_t nbytes, unsigned flags)
Splice from a pipe to the socket.
Definition: socket.h:296
socket(std::shared_ptr< event_loop > loop, int domain, int type, int protocol)
Construct a new socket object.
Definition: socket.h:56
sqe_awaitable write(void const *buf, size_t count)
Write data to the socket.
Definition: socket.h:149
sqe_awaitable tee(socket const &out, size_t count, unsigned int flags)
Tee the socket to another socket.
Definition: socket.h:271
sqe_awaitable tee(file const &out, size_t count, unsigned int flags)
Tee the socket to a file.
static task< socket > connect(std::shared_ptr< event_loop > loop, std::string const &hostname, std::string const &port)
Connect to a remote host.
Definition: socket.h:79
socket(std::shared_ptr< event_loop > loop, int fd)
Construct a new socket object from a file descriptor.
Definition: socket.h:67
sqe_awaitable writev(struct iovec const *iov, int iovcnt)
Vectorized write data to the socket.
Definition: socket.h:171
sqe_awaitable send(void const *buf, size_t len, int flags=0)
Send data to the socket.
Definition: socket.h:229
Definition: awaitable.h:10
Definition: task.h:53