maph 1.0.0 High-Performance Memory-Mapped Key-Value Database with O(1) Lookups

Loading...
Searching...
No Matches
socket.c
Go to the documentation of this file.
1/*
2 * Authored by Alex Hultman, 2018-2021.
3 * Intellectual property of third-party.
4
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8
9 * http://www.apache.org/licenses/LICENSE-2.0
10
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "libusockets.h"
19#include "internal/internal.h"
20#include <stdlib.h>
21#include <string.h>
22#include <stdint.h>
23
24/* Shared with SSL */
25
26 int us_socket_local_port(int ssl, struct us_socket_t *s) {
27 struct bsd_addr_t addr;
28 if (bsd_local_addr(us_poll_fd(&s->p), &addr)) {
29 return -1;
30 } else {
31 return bsd_addr_get_port(&addr);
32 }
33}
34
35 void us_socket_shutdown_read(int ssl, struct us_socket_t *s) {
36 /* This syscall is idempotent so no extra check is needed */
37 bsd_shutdown_socket_read(us_poll_fd((struct us_poll_t *) s));
38}
39
40 void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length) {
41 struct bsd_addr_t addr;
42 if (bsd_remote_addr(us_poll_fd(&s->p), &addr) || *length < bsd_addr_get_ip_length(&addr)) {
43 *length = 0;
44 } else {
45 *length = bsd_addr_get_ip_length(&addr);
46 memcpy(buf, bsd_addr_get_ip(&addr), *length);
47 }
48}
49
50 struct us_socket_context_t *us_socket_context(int ssl, struct us_socket_t *s) {
51 return s->context;
52}
53
54 void us_socket_timeout(int ssl, struct us_socket_t *s, unsigned int seconds) {
55 if (seconds) {
56 s->timeout = ((unsigned int)s->context->timestamp + ((seconds + 3) >> 2)) % 240;
57 } else {
58 s->timeout = 255;
59 }
60}
61
62 void us_socket_long_timeout(int ssl, struct us_socket_t *s, unsigned int minutes) {
63 if (minutes) {
64 s->long_timeout = ((unsigned int)s->context->long_timestamp + minutes) % 240;
65 } else {
66 s->long_timeout = 255;
67 }
68}
69
70 void us_socket_flush(int ssl, struct us_socket_t *s) {
71 if (!us_socket_is_shut_down(0, s)) {
72 bsd_socket_flush(us_poll_fd((struct us_poll_t *) s));
73 }
74}
75
76 int us_socket_is_closed(int ssl, struct us_socket_t *s) {
77 return s->prev == (struct us_socket_t *) s->context;
78}
79
80 int us_socket_is_established(int ssl, struct us_socket_t *s) {
81 /* Everything that is not POLL_TYPE_SEMI_SOCKET is established */
82 return us_internal_poll_type((struct us_poll_t *) s) != POLL_TYPE_SEMI_SOCKET;
83}
84
85/* Exactly the same as us_socket_close but does not emit on_close event */
86 struct us_socket_t *us_socket_close_connecting(int ssl, struct us_socket_t *s) {
87 if (!us_socket_is_closed(0, s)) {
88 us_internal_socket_context_unlink_socket(s->context, s);
89 us_poll_stop((struct us_poll_t *) s, s->context->loop);
90 bsd_close_socket(us_poll_fd((struct us_poll_t *) s));
91
92 /* Link this socket to the close-list and let it be deleted after this iteration */
93 s->next = s->context->loop->data.closed_head;
94 s->context->loop->data.closed_head = s;
95
96 /* Any socket with prev = context is marked as closed */
97 s->prev = (struct us_socket_t *) s->context;
98
99 //return s->context->on_close(s, code, reason);
100 }
101 return s;
102}
103
104/* Same as above but emits on_close */
105 struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, void *reason) {
106 if (!us_socket_is_closed(0, s)) {
107 if (s->low_prio_state == 1) {
108 /* Unlink this socket from the low-priority queue */
109 if (!s->prev) s->context->loop->data.low_prio_head = s->next;
110 else s->prev->next = s->next;
111
112 if (s->next) s->next->prev = s->prev;
113
114 s->prev = 0;
115 s->next = 0;
116 s->low_prio_state = 0;
117 } else {
118 us_internal_socket_context_unlink_socket(s->context, s);
119 }
120 us_poll_stop((struct us_poll_t *) s, s->context->loop);
121 bsd_close_socket(us_poll_fd((struct us_poll_t *) s));
122
123 /* Link this socket to the close-list and let it be deleted after this iteration */
124 s->next = s->context->loop->data.closed_head;
125 s->context->loop->data.closed_head = s;
126
127 /* Any socket with prev = context is marked as closed */
128 s->prev = (struct us_socket_t *) s->context;
129
130 return s->context->on_close(s, code, reason);
131 }
132 return s;
133}
134
135/* Not shared with SSL */
136
137 void *us_socket_get_native_handle(int ssl, struct us_socket_t *s) {
138#ifndef LIBUS_NO_SSL
139 if (ssl) {
140 return us_internal_ssl_socket_get_native_handle((struct us_internal_ssl_socket_t *) s);
141 }
142#endif
143
144 return (void *) (uintptr_t) us_poll_fd((struct us_poll_t *) s);
145}
146
147 int us_socket_write(int ssl, struct us_socket_t *s, const char *data, int length, int msg_more) {
148#ifndef LIBUS_NO_SSL
149 if (ssl) {
150 return us_internal_ssl_socket_write((struct us_internal_ssl_socket_t *) s, data, length, msg_more);
151 }
152#endif
153
154 if (us_socket_is_closed(ssl, s) || us_socket_is_shut_down(ssl, s)) {
155 return 0;
156 }
157
158 int written = bsd_send(us_poll_fd(&s->p), data, length, msg_more);
159 if (written != length) {
160 s->context->loop->data.last_write_failed = 1;
161 us_poll_change(&s->p, s->context->loop, LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
162 }
163
164 return written < 0 ? 0 : written;
165}
166
167 void *us_socket_ext(int ssl, struct us_socket_t *s) {
168#ifndef LIBUS_NO_SSL
169 if (ssl) {
170 return us_internal_ssl_socket_ext((struct us_internal_ssl_socket_t *) s);
171 }
172#endif
173
174 return s + 1;
175}
176
177 int us_socket_is_shut_down(int ssl, struct us_socket_t *s) {
178#ifndef LIBUS_NO_SSL
179 if (ssl) {
180 return us_internal_ssl_socket_is_shut_down((struct us_internal_ssl_socket_t *) s);
181 }
182#endif
183
184 return us_internal_poll_type(&s->p) == POLL_TYPE_SOCKET_SHUT_DOWN;
185}
186
187 void us_socket_shutdown(int ssl, struct us_socket_t *s) {
188#ifndef LIBUS_NO_SSL
189 if (ssl) {
190 us_internal_ssl_socket_shutdown((struct us_internal_ssl_socket_t *) s);
191 return;
192 }
193#endif
194
195 /* Todo: should we emit on_close if calling shutdown on an already half-closed socket?
196 * We need more states in that case, we need to track RECEIVED_FIN
197 * so far, the app has to track this and call close as needed */
198 if (!us_socket_is_closed(ssl, s) && !us_socket_is_shut_down(ssl, s)) {
199 us_internal_poll_set_type(&s->p, POLL_TYPE_SOCKET_SHUT_DOWN);
200 us_poll_change(&s->p, s->context->loop, us_poll_events(&s->p) & LIBUS_SOCKET_READABLE);
201 bsd_shutdown_socket(us_poll_fd((struct us_poll_t *) s));
202 }
203}
LIBUS_SOCKET_WRITABLE
#define LIBUS_SOCKET_WRITABLE
Definition asio.h:24
LIBUS_SOCKET_READABLE
#define LIBUS_SOCKET_READABLE
Definition asio.h:23
bsd_shutdown_socket_read
void bsd_shutdown_socket_read(int fd)
Definition bsd.c:318
bsd_addr_get_ip
char * bsd_addr_get_ip(struct bsd_addr_t *addr)
Definition bsd.c:360
bsd_close_socket
void bsd_close_socket(int fd)
Definition bsd.c:302
bsd_socket_flush
void bsd_socket_flush(int fd)
Definition bsd.c:282
bsd_addr_get_ip_length
int bsd_addr_get_ip_length(struct bsd_addr_t *addr)
Definition bsd.c:364
bsd_remote_addr
int bsd_remote_addr(int fd, struct bsd_addr_t *addr)
Definition bsd.c:351
bsd_addr_get_port
int bsd_addr_get_port(struct bsd_addr_t *addr)
Definition bsd.c:368
bsd_send
int bsd_send(int fd, const char *buf, int length, int msg_more)
Definition bsd.c:400
bsd_shutdown_socket
void bsd_shutdown_socket(int fd)
Definition bsd.c:310
bsd_local_addr
int bsd_local_addr(int fd, struct bsd_addr_t *addr)
Definition bsd.c:342
bsd_addr_t
Definition bsd.h:50
us_internal_socket_context_unlink_socket
void us_internal_socket_context_unlink_socket(struct us_socket_context_t *context, struct us_socket_t *s)
Definition context.c:89
internal.h
us_internal_poll_set_type
void us_internal_poll_set_type(struct us_poll_t *p, int poll_type)
us_socket_t::p
struct us_poll_t p
Definition internal.h:90
us_internal_ssl_socket_ext
void * us_internal_ssl_socket_ext(struct us_internal_ssl_socket_t *s)
us_socket_t::long_timeout
unsigned char long_timeout
Definition internal.h:92
us_socket_t::next
struct us_socket_t * next
Definition internal.h:95
us_internal_ssl_socket_get_native_handle
void * us_internal_ssl_socket_get_native_handle(struct us_internal_ssl_socket_t *s)
us_socket_t::timeout
unsigned char timeout
Definition internal.h:91
us_socket_t::prev
struct us_socket_t * prev
Definition internal.h:95
us_internal_poll_type
int us_internal_poll_type(struct us_poll_t *p)
us_socket_t::low_prio_state
unsigned short low_prio_state
Definition internal.h:93
us_socket_t::context
struct us_socket_context_t * context
Definition internal.h:94
us_internal_ssl_socket_is_shut_down
int us_internal_ssl_socket_is_shut_down(struct us_internal_ssl_socket_t *s)
us_internal_ssl_socket_shutdown
void us_internal_ssl_socket_shutdown(struct us_internal_ssl_socket_t *s)
POLL_TYPE_SEMI_SOCKET
@ POLL_TYPE_SEMI_SOCKET
Definition internal.h:49
POLL_TYPE_SOCKET_SHUT_DOWN
@ POLL_TYPE_SOCKET_SHUT_DOWN
Definition internal.h:48
us_internal_ssl_socket_write
int us_internal_ssl_socket_write(struct us_internal_ssl_socket_t *s, const char *data, int length, int msg_more)
us_socket_t
Definition internal.h:89
libusockets.h
us_poll_change
void us_poll_change(struct us_poll_t *p, struct us_loop_t *loop, int events)
us_poll_fd
int us_poll_fd(struct us_poll_t *p)
us_poll_events
int us_poll_events(struct us_poll_t *p)
us_poll_stop
void us_poll_stop(struct us_poll_t *p, struct us_loop_t *loop)
us_loop_t::data
struct us_internal_loop_data_t data
Definition asio.h:27
us_poll_t
Definition asio.h:37
us_socket_is_established
int us_socket_is_established(int ssl, struct us_socket_t *s)
Definition socket.c:80
us_socket_remote_address
void us_socket_remote_address(int ssl, struct us_socket_t *s, char *buf, int *length)
Definition socket.c:40
us_socket_write
int us_socket_write(int ssl, struct us_socket_t *s, const char *data, int length, int msg_more)
Definition socket.c:147
us_socket_close_connecting
struct us_socket_t * us_socket_close_connecting(int ssl, struct us_socket_t *s)
Definition socket.c:86
us_socket_is_shut_down
int us_socket_is_shut_down(int ssl, struct us_socket_t *s)
Definition socket.c:177
us_socket_shutdown_read
void us_socket_shutdown_read(int ssl, struct us_socket_t *s)
Definition socket.c:35
us_socket_local_port
int us_socket_local_port(int ssl, struct us_socket_t *s)
Definition socket.c:26
us_socket_flush
void us_socket_flush(int ssl, struct us_socket_t *s)
Definition socket.c:70
us_socket_get_native_handle
void * us_socket_get_native_handle(int ssl, struct us_socket_t *s)
Definition socket.c:137
us_socket_shutdown
void us_socket_shutdown(int ssl, struct us_socket_t *s)
Definition socket.c:187
us_socket_long_timeout
void us_socket_long_timeout(int ssl, struct us_socket_t *s, unsigned int minutes)
Definition socket.c:62
us_socket_context
struct us_socket_context_t * us_socket_context(int ssl, struct us_socket_t *s)
Definition socket.c:50
us_socket_close
struct us_socket_t * us_socket_close(int ssl, struct us_socket_t *s, int code, void *reason)
Definition socket.c:105
us_socket_timeout
void us_socket_timeout(int ssl, struct us_socket_t *s, unsigned int seconds)
Definition socket.c:54
us_socket_ext
void * us_socket_ext(int ssl, struct us_socket_t *s)
Definition socket.c:167
us_socket_is_closed
int us_socket_is_closed(int ssl, struct us_socket_t *s)
Definition socket.c:76
us_internal_loop_data_t::low_prio_head
struct us_socket_t * low_prio_head
Definition loop_data.h:32
us_internal_loop_data_t::last_write_failed
int last_write_failed
Definition loop_data.h:24
us_socket_context_t
Definition internal.h:117
us_socket_context_t::long_timestamp
unsigned char long_timestamp
Definition internal.h:121
us_socket_context_t::timestamp
unsigned char timestamp
Definition internal.h:120
us_socket_context_t::loop
struct us_loop_t * loop
Definition internal.h:118