├── Makefile └── src ├── hev-dns-forwarder.c ├── hev-dns-forwarder.h ├── hev-dns-session.c ├── hev-dns-session.h ├── hev-event-loop.c ├── hev-event-loop.h ├── hev-event-source-fd.h ├── hev-event-source-fds.c ├── hev-event-source-fds.h ├── hev-event-source-signal.c ├── hev-event-source-signal.h ├── hev-event-source-timeout.c ├── hev-event-source-timeout.h ├── hev-event-source.c ├── hev-event-source.h ├── hev-main.c ├── hev-main.h ├── hev-memory-allocator.c ├── hev-memory-allocator.h ├── hev-ring-buffer.c ├── hev-ring-buffer.h ├── hev-slist.c └── hev-slist.h /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for hev-dns-forwarder 2 | 3 | PP=cpp 4 | CC=cc 5 | CCFLAGS=-O3 -Werror -Wall 6 | LDFLAGS= 7 | 8 | SRCDIR=src 9 | BINDIR=src 10 | BUILDDIR=src 11 | 12 | TARGET=$(BINDIR)/hev-dns-forwarder 13 | CCOBJSFILE=$(BUILDDIR)/ccobjs 14 | -include $(CCOBJSFILE) 15 | LDOBJS=$(patsubst $(SRCDIR)%.c,$(BUILDDIR)%.o,$(CCOBJS)) 16 | 17 | DEPEND=$(LDOBJS:.o=.dep) 18 | 19 | all : $(CCOBJSFILE) $(TARGET) 20 | @$(RM) $(CCOBJSFILE) 21 | 22 | clean : 23 | @echo -n "Clean ... " && $(RM) $(TARGET) $(CCOBJSFILE) $(BUILDDIR)/*.dep $(BUILDDIR)/*.o && echo "OK" 24 | 25 | run : 26 | @$(TARGET) 27 | 28 | $(CCOBJSFILE) : 29 | @mkdir -p $(BINDIR) $(BUILDDIR) 30 | @echo CCOBJS=`ls $(SRCDIR)/*.c` > $(CCOBJSFILE) 31 | 32 | $(TARGET) : $(LDOBJS) 33 | @echo -n "Linking $^ to $@ ... " && $(CC) -o $@ $^ $(LDFLAGS) && echo "OK" 34 | 35 | $(BUILDDIR)/%.dep : $(SRCDIR)/%.c 36 | @$(PP) $(CCFLAGS) -MM -MT $(@:.dep=.o) -o $@ $< 37 | 38 | $(BUILDDIR)/%.o : $(SRCDIR)/%.c 39 | @echo -n "Building $< ... " && $(CC) $(CCFLAGS) -c -o $@ $< && echo "OK" 40 | 41 | -include $(DEPEND) 42 | -------------------------------------------------------------------------------- /src/hev-dns-forwarder.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-dns-forwarder.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : DNS Forwarder 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include "hev-dns-forwarder.h" 22 | #include "hev-dns-session.h" 23 | 24 | #define TIMEOUT (10 * 1000) 25 | 26 | struct _HevDNSForwarder 27 | { 28 | int listen_fd; 29 | unsigned int ref_count; 30 | HevEventSource *listener_source; 31 | HevEventSource *timeout_source; 32 | HevSList *session_list; 33 | 34 | HevEventLoop *loop; 35 | struct sockaddr_in upstream; 36 | }; 37 | 38 | static bool listener_source_handler (HevEventSourceFD *fd, void *data); 39 | static bool timeout_source_handler (void *data); 40 | static void session_close_handler (HevDNSSession *session, void *data); 41 | static void remove_all_sessions (HevDNSForwarder *self); 42 | 43 | HevDNSForwarder * 44 | hev_dns_forwarder_new (HevEventLoop *loop, const char *addr, const char *port, 45 | const char *upstream, const char *upstream_port) 46 | { 47 | HevDNSForwarder *self = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevDNSForwarder)); 48 | if (self) { 49 | int r, nonblock = 1, reuseaddr = 1; 50 | struct addrinfo hints; 51 | struct addrinfo *addr_ip; 52 | 53 | /* listen socket */ 54 | self->listen_fd = socket (AF_INET, SOCK_DGRAM, 0); 55 | if (0 > self->listen_fd) { 56 | HEV_MEMORY_ALLOCATOR_FREE (self); 57 | fprintf (stderr, "socket error\n"); 58 | return NULL; 59 | } 60 | ioctl (self->listen_fd, FIONBIO, (char *) &nonblock); 61 | setsockopt (self->listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof (reuseaddr)); 62 | memset(&hints, 0, sizeof(hints)); 63 | hints.ai_family = AF_INET; 64 | hints.ai_socktype = SOCK_DGRAM; 65 | if (0 != (r = getaddrinfo(addr, port, &hints, &addr_ip))) { 66 | fprintf(stderr, "%s:%s:%s\n", gai_strerror(r), addr, port); 67 | return NULL; 68 | } 69 | if (0 != bind(self->listen_fd, addr_ip->ai_addr, addr_ip->ai_addrlen)) { 70 | close (self->listen_fd); 71 | HEV_MEMORY_ALLOCATOR_FREE (self); 72 | fprintf (stderr, "Can't bind address %s:%s\n", addr, port); 73 | return NULL; 74 | } 75 | freeaddrinfo(addr_ip); 76 | 77 | /* event source fds for listener */ 78 | self->listener_source = hev_event_source_fds_new (); 79 | hev_event_source_set_priority (self->listener_source, 1); 80 | hev_event_source_add_fd (self->listener_source, self->listen_fd, EPOLLIN | EPOLLET); 81 | hev_event_source_set_callback (self->listener_source, 82 | (HevEventSourceFunc) listener_source_handler, self, NULL); 83 | hev_event_loop_add_source (loop, self->listener_source); 84 | hev_event_source_unref (self->listener_source); 85 | 86 | /* event source timeout */ 87 | self->timeout_source = hev_event_source_timeout_new (TIMEOUT); 88 | hev_event_source_set_priority (self->timeout_source, -1); 89 | hev_event_source_set_callback (self->timeout_source, timeout_source_handler, self, NULL); 90 | hev_event_loop_add_source (loop, self->timeout_source); 91 | hev_event_source_unref (self->timeout_source); 92 | 93 | self->ref_count = 1; 94 | self->session_list = NULL; 95 | self->loop = loop; 96 | 97 | /* upstream address */ 98 | memset (&self->upstream, 0, sizeof (self->upstream)); 99 | self->upstream.sin_family = AF_INET; 100 | if (0 == inet_aton (upstream, &self->upstream.sin_addr)) { 101 | fprintf (stderr, "invalid upstream %s\n", upstream); 102 | return NULL; 103 | } 104 | self->upstream.sin_port = htons (atoi (upstream_port)); 105 | } 106 | 107 | return self; 108 | } 109 | 110 | HevDNSForwarder * 111 | hev_dns_forwarder_ref (HevDNSForwarder *self) 112 | { 113 | if (self) { 114 | self->ref_count ++; 115 | return self; 116 | } 117 | 118 | return NULL; 119 | } 120 | 121 | void 122 | hev_dns_forwarder_unref (HevDNSForwarder *self) 123 | { 124 | if (self) { 125 | self->ref_count --; 126 | if (0 == self->ref_count) { 127 | hev_event_loop_del_source (self->loop, self->listener_source); 128 | hev_event_loop_del_source (self->loop, self->timeout_source); 129 | close (self->listen_fd); 130 | remove_all_sessions (self); 131 | HEV_MEMORY_ALLOCATOR_FREE (self); 132 | } 133 | } 134 | } 135 | 136 | static bool 137 | listener_source_handler (HevEventSourceFD *fd, void *data) 138 | { 139 | HevDNSForwarder *self = data; 140 | HevDNSSession *session = NULL; 141 | HevEventSource *source = NULL; 142 | ssize_t size; 143 | 144 | size = recvfrom (fd->fd, NULL, 0, MSG_PEEK, NULL, NULL); 145 | if (0 > size) { 146 | if (EAGAIN == errno) 147 | fd->revents &= ~EPOLLIN; 148 | } else { 149 | session = hev_dns_session_new (fd->fd, &self->upstream, session_close_handler, self); 150 | source = hev_dns_session_get_source (session); 151 | hev_event_loop_add_source (self->loop, source); 152 | /* printf ("New session %p\n", session); */ 153 | self->session_list = hev_slist_append (self->session_list, session); 154 | hev_dns_session_start (session); 155 | } 156 | 157 | return true; 158 | } 159 | 160 | static bool 161 | timeout_source_handler (void *data) 162 | { 163 | HevDNSForwarder *self = data; 164 | HevSList *list = NULL; 165 | for (list=self->session_list; list; list=hev_slist_next (list)) { 166 | HevDNSSession *session = hev_slist_data (list); 167 | if (hev_dns_session_get_idle (session)) { 168 | /* printf ("Remove timeout session %p\n", session); */ 169 | hev_event_loop_del_source (self->loop, 170 | hev_dns_session_get_source (session)); 171 | hev_dns_session_unref (session); 172 | hev_slist_set_data (list, NULL); 173 | } else { 174 | hev_dns_session_set_idle (session); 175 | } 176 | } 177 | self->session_list = hev_slist_remove_all (self->session_list, NULL); 178 | 179 | return true; 180 | } 181 | 182 | static void 183 | session_close_handler (HevDNSSession *session, void *data) 184 | { 185 | HevDNSForwarder *self = data; 186 | 187 | /* printf ("Remove session %p\n", session); */ 188 | hev_event_loop_del_source (self->loop, 189 | hev_dns_session_get_source (session)); 190 | hev_dns_session_unref (session); 191 | self->session_list = hev_slist_remove (self->session_list, session); 192 | } 193 | 194 | static void 195 | remove_all_sessions (HevDNSForwarder *self) 196 | { 197 | HevSList *list = NULL; 198 | for (list=self->session_list; list; list=hev_slist_next (list)) { 199 | HevDNSSession *session = hev_slist_data (list); 200 | /* printf ("Remove session %p\n", session); */ 201 | hev_event_loop_del_source (self->loop, 202 | hev_dns_session_get_source (session)); 203 | hev_dns_session_unref (session); 204 | } 205 | hev_slist_free (self->session_list); 206 | } 207 | 208 | -------------------------------------------------------------------------------- /src/hev-dns-forwarder.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-dns-forwarder.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : DNS Forwarder 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_DNS_FORWARDER_H__ 11 | #define __HEV_DNS_FORWARDER_H__ 12 | 13 | #include "hev-dns-session.h" 14 | #include "hev-event-source-timeout.h" 15 | 16 | typedef struct _HevDNSForwarder HevDNSForwarder; 17 | 18 | HevDNSForwarder * hev_dns_forwarder_new (HevEventLoop *loop, 19 | const char *addr, const char *port, 20 | const char *upstream, const char *upstream_port); 21 | 22 | HevDNSForwarder * hev_dns_forwarder_ref (HevDNSForwarder *self); 23 | void hev_dns_forwarder_unref (HevDNSForwarder *self); 24 | 25 | #endif /* __HEV_DNS_FORWARDER_H__ */ 26 | 27 | -------------------------------------------------------------------------------- /src/hev-dns-session.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-dns-session.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : DNS session 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "hev-dns-session.h" 19 | 20 | enum 21 | { 22 | REMOTE_IN = (1 << 1), 23 | REMOTE_OUT = (1 << 0), 24 | }; 25 | 26 | enum 27 | { 28 | STEP_NULL, 29 | STEP_WAIT_CONNECT, 30 | STEP_WRITE_REQUEST, 31 | STEP_READ_RESPONSE, 32 | STEP_WRITE_RESPONSE, 33 | STEP_CLOSE_SESSION, 34 | }; 35 | 36 | struct _HevDNSSession 37 | { 38 | int cfd; 39 | int rfd; 40 | unsigned int ref_count; 41 | unsigned int step; 42 | bool idle; 43 | uint8_t revents; 44 | HevEventSourceFD *remote_fd; 45 | HevRingBuffer *forward_buffer; 46 | HevRingBuffer *backward_buffer; 47 | HevEventSource *source; 48 | HevDNSSessionCloseNotify notify; 49 | void *notify_data; 50 | struct sockaddr_in *upstream; 51 | struct sockaddr_in client_addr; 52 | }; 53 | 54 | static int dns_read_request (HevDNSSession *self); 55 | static void dns_do_connect (HevDNSSession *self); 56 | static void dns_close_session (HevDNSSession *self); 57 | static bool session_source_forward_handler (HevEventSourceFD *fd, void *data); 58 | 59 | HevDNSSession * 60 | hev_dns_session_new (int fd, struct sockaddr_in *upstream, 61 | HevDNSSessionCloseNotify notify, void *notify_data) 62 | { 63 | HevDNSSession *self = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevDNSSession)); 64 | if (self) { 65 | self->ref_count = 1; 66 | self->cfd = fd; 67 | self->rfd = -1; 68 | self->revents = 0; 69 | self->idle = false; 70 | self->remote_fd = NULL; 71 | self->forward_buffer = hev_ring_buffer_new (2000); 72 | self->backward_buffer = hev_ring_buffer_new (2000); 73 | self->source = NULL; 74 | self->step = STEP_NULL; 75 | self->notify = notify; 76 | self->upstream = upstream; 77 | self->notify_data = notify_data; 78 | } 79 | 80 | return self; 81 | } 82 | 83 | HevDNSSession * 84 | hev_dns_session_ref (HevDNSSession *self) 85 | { 86 | if (self) 87 | self->ref_count ++; 88 | 89 | return self; 90 | } 91 | 92 | void 93 | hev_dns_session_unref (HevDNSSession *self) 94 | { 95 | if (self) { 96 | self->ref_count --; 97 | if (0 == self->ref_count) { 98 | if (-1 < self->rfd) 99 | close (self->rfd); 100 | hev_ring_buffer_unref (self->forward_buffer); 101 | hev_ring_buffer_unref (self->backward_buffer); 102 | if (self->source) 103 | hev_event_source_unref (self->source); 104 | HEV_MEMORY_ALLOCATOR_FREE (self); 105 | } 106 | } 107 | } 108 | 109 | HevEventSource * 110 | hev_dns_session_get_source (HevDNSSession *self) 111 | { 112 | if (self) { 113 | if (self->source) 114 | return self->source; 115 | self->source = hev_event_source_fds_new (); 116 | if (self->source) { 117 | hev_event_source_set_callback (self->source, 118 | (HevEventSourceFunc) session_source_forward_handler, self, NULL); 119 | } 120 | return self->source; 121 | } 122 | 123 | return NULL; 124 | } 125 | 126 | void 127 | hev_dns_session_start (HevDNSSession *self) 128 | { 129 | if (self) { 130 | if (0 <= dns_read_request (self)) 131 | dns_do_connect (self); 132 | } 133 | } 134 | 135 | void 136 | hev_dns_session_set_idle (HevDNSSession *self) 137 | { 138 | if (self) 139 | self->idle = true; 140 | } 141 | 142 | bool 143 | hev_dns_session_get_idle (HevDNSSession *self) 144 | { 145 | return self ? self->idle : false; 146 | } 147 | 148 | static size_t 149 | iovec_size (struct iovec *iovec, size_t iovec_len) 150 | { 151 | size_t i = 0, size = 0; 152 | 153 | for (i=0; i size) ? 0 : size; 179 | hev_ring_buffer_write_finish (buffer, inc_len); 180 | } 181 | 182 | return size; 183 | } 184 | 185 | static ssize_t 186 | write_data (int fd, HevRingBuffer *buffer, struct sockaddr_in *addr) 187 | { 188 | struct msghdr mh; 189 | struct iovec iovec[2]; 190 | size_t iovec_len = 0, inc_len = 0; 191 | ssize_t size = -2; 192 | 193 | iovec_len = hev_ring_buffer_reading (buffer, iovec); 194 | if (0 < iovec_len) { 195 | /* send data */ 196 | memset (&mh, 0, sizeof (mh)); 197 | if (addr) { 198 | mh.msg_name = addr; 199 | mh.msg_namelen = sizeof (struct sockaddr_in); 200 | } 201 | mh.msg_iov = iovec; 202 | mh.msg_iovlen = iovec_len; 203 | size = sendmsg (fd, &mh, 0); 204 | inc_len = (0 > size) ? 0 : size; 205 | hev_ring_buffer_read_finish (buffer, inc_len); 206 | } 207 | 208 | return size; 209 | } 210 | 211 | static bool 212 | remote_read (HevDNSSession *self) 213 | { 214 | ssize_t size = read_data (self->remote_fd->fd, self->backward_buffer, NULL); 215 | if (-2 < size) { 216 | if (-1 == size) { 217 | if (EAGAIN == errno) { 218 | self->revents &= ~REMOTE_IN; 219 | self->remote_fd->revents &= ~EPOLLIN; 220 | } else { 221 | return false; 222 | } 223 | } else if (0 == size) { 224 | return false; 225 | } 226 | } else { 227 | self->remote_fd->revents &= ~EPOLLIN; 228 | } 229 | 230 | return true; 231 | } 232 | 233 | static bool 234 | remote_write (HevDNSSession *self) 235 | { 236 | ssize_t size = write_data (self->remote_fd->fd, self->forward_buffer, NULL); 237 | if (-2 < size) { 238 | if (-1 == size) { 239 | if (EAGAIN == errno) { 240 | self->revents &= ~REMOTE_OUT; 241 | self->remote_fd->revents &= ~EPOLLOUT; 242 | } else { 243 | return false; 244 | } 245 | } 246 | } else { 247 | self->remote_fd->revents &= ~EPOLLOUT; 248 | } 249 | 250 | return true; 251 | } 252 | 253 | static int 254 | dns_read_request (HevDNSSession *self) 255 | { 256 | ssize_t size; 257 | struct iovec iovec[2]; 258 | unsigned short *plen; 259 | 260 | hev_ring_buffer_writing (self->forward_buffer, iovec); 261 | hev_ring_buffer_write_finish (self->forward_buffer, 2); 262 | size = read_data (self->cfd, self->forward_buffer, &self->client_addr); 263 | if (0 > size) { 264 | dns_close_session (self); 265 | return -1; 266 | } 267 | 268 | plen = iovec[0].iov_base; 269 | *plen = htons (size); 270 | 271 | return 0; 272 | } 273 | 274 | static void 275 | dns_do_connect (HevDNSSession *self) 276 | { 277 | int nonblock = 1; 278 | 279 | self->rfd = socket (AF_INET, SOCK_STREAM, 0); 280 | if (-1 == self->rfd) { 281 | dns_close_session (self); 282 | return; 283 | } 284 | ioctl (self->rfd, FIONBIO, (char *) &nonblock); 285 | /* add fd to source */ 286 | if (self->source) 287 | self->remote_fd = hev_event_source_add_fd (self->source, 288 | self->rfd, EPOLLIN | EPOLLOUT | EPOLLET); 289 | /* connect to remote host */ 290 | if (0 > connect (self->rfd, (struct sockaddr *) self->upstream, sizeof (struct sockaddr_in))) { 291 | if (EINPROGRESS != errno) { 292 | dns_close_session (self); 293 | return; 294 | } 295 | } 296 | } 297 | 298 | static bool 299 | dns_wait_connect (HevDNSSession *self) 300 | { 301 | if (!(REMOTE_OUT & self->revents)) 302 | return true; 303 | 304 | self->step = STEP_WRITE_REQUEST; 305 | 306 | return false; 307 | } 308 | 309 | static bool 310 | dns_write_request (HevDNSSession *self) 311 | { 312 | self->step = STEP_READ_RESPONSE; 313 | 314 | return false; 315 | } 316 | 317 | static bool 318 | dns_read_response (HevDNSSession *self) 319 | { 320 | struct iovec iovec[2]; 321 | size_t iovec_len = 0, size = 0; 322 | unsigned short *plen, len; 323 | 324 | iovec_len = hev_ring_buffer_reading (self->backward_buffer, iovec); 325 | size = iovec_size (iovec, iovec_len); 326 | if (2 > size) 327 | return true; 328 | plen = iovec[0].iov_base; 329 | len = ntohs (*plen); 330 | if ((len + 2) > size) 331 | return true; 332 | 333 | self->step = STEP_WRITE_RESPONSE; 334 | hev_ring_buffer_read_finish (self->backward_buffer, 2); 335 | 336 | return false; 337 | } 338 | 339 | static bool 340 | dns_write_response (HevDNSSession *self) 341 | { 342 | write_data (self->cfd, self->backward_buffer, &self->client_addr); 343 | self->step = STEP_CLOSE_SESSION; 344 | 345 | return false; 346 | } 347 | 348 | static void 349 | dns_close_session (HevDNSSession *self) 350 | { 351 | if (self->notify) 352 | self->notify (self, self->notify_data); 353 | } 354 | 355 | static int 356 | handle_forward (HevDNSSession *self) 357 | { 358 | bool wait = false; 359 | 360 | switch (self->step) { 361 | case STEP_NULL: 362 | self->step = STEP_WAIT_CONNECT; 363 | case STEP_WAIT_CONNECT: 364 | wait = dns_wait_connect (self); 365 | break; 366 | case STEP_WRITE_REQUEST: 367 | wait = dns_write_request (self); 368 | break; 369 | case STEP_READ_RESPONSE: 370 | wait = dns_read_response (self); 371 | break; 372 | case STEP_WRITE_RESPONSE: 373 | wait = dns_write_response (self); 374 | break; 375 | case STEP_CLOSE_SESSION: 376 | default: 377 | return -1; 378 | } 379 | 380 | return wait ? 1 : 0; 381 | } 382 | static bool 383 | session_source_forward_handler (HevEventSourceFD *fd, void *data) 384 | { 385 | HevDNSSession *self = data; 386 | int wait = -1; 387 | 388 | if ((EPOLLERR | EPOLLHUP) & fd->revents) 389 | goto close_session; 390 | 391 | if (fd == self->remote_fd) { 392 | if (EPOLLIN & fd->revents) 393 | self->revents |= REMOTE_IN; 394 | if (EPOLLOUT & fd->revents) 395 | self->revents |= REMOTE_OUT; 396 | } 397 | 398 | do { 399 | if (REMOTE_OUT & self->revents) { 400 | if (!remote_write (self)) 401 | goto close_session; 402 | } 403 | if (REMOTE_IN & self->revents) { 404 | if (!remote_read (self)) 405 | goto close_session; 406 | } 407 | 408 | wait = handle_forward (self); 409 | if (-1 == wait) 410 | goto close_session; 411 | } while (0 == wait); 412 | 413 | self->idle = false; 414 | 415 | return true; 416 | 417 | close_session: 418 | dns_close_session (self); 419 | 420 | return true; 421 | } 422 | 423 | -------------------------------------------------------------------------------- /src/hev-dns-session.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-dns-session.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : DNS session 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_DNS_SESSION_H__ 11 | #define __HEV_DNS_SESSION_H__ 12 | 13 | #include 14 | #include 15 | 16 | #include "hev-ring-buffer.h" 17 | #include "hev-event-source.h" 18 | #include "hev-event-source-fds.h" 19 | 20 | typedef struct _HevDNSSession HevDNSSession; 21 | typedef void (*HevDNSSessionCloseNotify) (HevDNSSession *self, void *data); 22 | 23 | HevDNSSession * hev_dns_session_new (int fd, struct sockaddr_in *upstream, 24 | HevDNSSessionCloseNotify notify, void *notify_data); 25 | 26 | HevDNSSession * hev_dns_session_ref (HevDNSSession *self); 27 | void hev_dns_session_unref (HevDNSSession *self); 28 | 29 | HevEventSource * hev_dns_session_get_source (HevDNSSession *self); 30 | void hev_dns_session_start (HevDNSSession *self); 31 | 32 | void hev_dns_session_set_idle (HevDNSSession *self); 33 | bool hev_dns_session_get_idle (HevDNSSession *self); 34 | 35 | #endif /* __HEV_DNS_SESSION_H__ */ 36 | 37 | -------------------------------------------------------------------------------- /src/hev-event-loop.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-loop.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : An event loop 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "hev-slist.h" 17 | #include "hev-event-loop.h" 18 | 19 | struct _HevEventLoop 20 | { 21 | int epoll_fd; 22 | unsigned int ref_count; 23 | 24 | bool run; 25 | HevSList *sources; 26 | }; 27 | 28 | HevEventLoop * 29 | hev_event_loop_new (void) 30 | { 31 | HevEventLoop *self = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevEventLoop)); 32 | 33 | if (self) { 34 | self->epoll_fd = epoll_create (1024); 35 | self->ref_count = 1; 36 | self->run = true; 37 | self->sources = NULL; 38 | } 39 | 40 | return self; 41 | } 42 | 43 | HevEventLoop * 44 | hev_event_loop_ref (HevEventLoop *self) 45 | { 46 | if (self) 47 | self->ref_count ++; 48 | 49 | return self; 50 | } 51 | 52 | void 53 | hev_event_loop_unref (HevEventLoop *self) 54 | { 55 | if (self) { 56 | self->ref_count --; 57 | if (0 == self->ref_count) { 58 | HevSList *list = NULL; 59 | for (list=self->sources; list; list=hev_slist_next (list)) { 60 | HevEventSource *source = hev_slist_data (list); 61 | _hev_event_source_set_loop (source, NULL); 62 | hev_event_source_unref (source); 63 | } 64 | hev_slist_free (self->sources); 65 | close (self->epoll_fd); 66 | HEV_MEMORY_ALLOCATOR_FREE (self); 67 | } 68 | } 69 | } 70 | 71 | static HevSList * 72 | insert_event_source_fd_sorted (HevSList *fd_list, HevEventSourceFD *fd) 73 | { 74 | HevSList *list = NULL; 75 | 76 | for (list=fd_list; list; list=hev_slist_next (list)) { 77 | HevEventSourceFD *_fd = hev_slist_data (list); 78 | if (hev_event_source_get_priority (fd->source) > 79 | hev_event_source_get_priority (_fd->source)) 80 | break; 81 | } 82 | return hev_slist_insert_before (fd_list, fd, list); 83 | } 84 | 85 | void 86 | hev_event_loop_run (HevEventLoop *self) 87 | { 88 | int timeout = -1; 89 | HevSList *fd_list = NULL; 90 | 91 | if (!self) 92 | return; 93 | 94 | while (self->run) { 95 | int i = 0, nfds = 0; 96 | struct epoll_event events[256]; 97 | 98 | /* waiting events */ 99 | nfds = epoll_wait (self->epoll_fd, events, 256, timeout); 100 | if (-1 == nfds && EINTR != errno) { 101 | fprintf (stderr, "EPoll wait failed!\n"); 102 | break; 103 | } 104 | /* insert to fd_list, sorted by source priority (highest ... lowest) */ 105 | for (i=0; irevents |= events[i].events; 108 | fd = _hev_event_source_fd_ref (fd); 109 | fd_list = insert_event_source_fd_sorted (fd_list, fd); 110 | } 111 | /* get highest priority source fd, check & dispatch */ 112 | if (fd_list) { 113 | HevSList *invalid_sources = NULL; 114 | HevEventSourceFD *fd = hev_slist_data (fd_list); 115 | HevEventSource *source = fd->source; 116 | if (source && (hev_event_source_get_loop (source) == self) && 117 | source->funcs.check (source, fd)) { 118 | bool res = source->funcs.dispatch (source, fd, 119 | source->callback.callback, source->callback.data); 120 | /* recheck, in user's dispatch, source and fd may be remove. */ 121 | if (fd->source) { 122 | if (res) { 123 | if (hev_event_source_get_loop (source) == self) 124 | source->funcs.prepare (source); 125 | } else { 126 | fd->revents = 0; 127 | invalid_sources = hev_slist_append (invalid_sources, source); 128 | } 129 | } 130 | } 131 | if (!(fd->_events & fd->revents) || !fd->source) { 132 | fd_list = hev_slist_remove (fd_list, fd); 133 | _hev_event_source_fd_unref (fd); 134 | } 135 | /* delete invalid sources */ 136 | if (invalid_sources) { 137 | HevSList *list = NULL; 138 | for (list=invalid_sources; list; list=hev_slist_next (list)) 139 | hev_event_loop_del_source (self, hev_slist_data (list)); 140 | hev_slist_free (invalid_sources); 141 | } 142 | timeout = 0; 143 | } else { 144 | timeout = -1; 145 | } 146 | } 147 | /* free fd_list */ 148 | hev_slist_free (fd_list); 149 | } 150 | 151 | void 152 | hev_event_loop_quit (HevEventLoop *self) 153 | { 154 | if (self) 155 | self->run = false; 156 | } 157 | 158 | bool 159 | hev_event_loop_add_source (HevEventLoop *self, HevEventSource *source) 160 | { 161 | if (self && source) { 162 | HevSList *list = NULL; 163 | for (list=self->sources; list; list=hev_slist_next (list)) { 164 | if (source == hev_slist_data (list)) 165 | return false; 166 | } 167 | _hev_event_source_set_loop (source, self); 168 | self->sources = hev_slist_append (self->sources, hev_event_source_ref (source)); 169 | for (list=source->fds; list; list=hev_slist_next (list)) { 170 | HevEventSourceFD *fd = hev_slist_data (list); 171 | _hev_event_loop_add_fd (self, fd); 172 | } 173 | source->funcs.prepare (source); 174 | return true; 175 | } 176 | 177 | return false; 178 | } 179 | 180 | bool 181 | hev_event_loop_del_source (HevEventLoop *self, HevEventSource *source) 182 | { 183 | if (self && source) { 184 | HevSList *list = NULL; 185 | for (list=self->sources; list; list=hev_slist_next (list)) { 186 | if (source == hev_slist_data (list)) 187 | break; 188 | } 189 | if (list) { 190 | _hev_event_source_set_loop (source, NULL); 191 | self->sources = hev_slist_remove (self->sources, source); 192 | for (list=source->fds; list; list=hev_slist_next (list)) { 193 | HevEventSourceFD *fd = hev_slist_data (list); 194 | _hev_event_loop_del_fd (self, fd); 195 | } 196 | hev_event_source_unref (source); 197 | return true; 198 | } 199 | } 200 | 201 | return false; 202 | } 203 | 204 | bool 205 | _hev_event_loop_add_fd (HevEventLoop *self, HevEventSourceFD *fd) 206 | { 207 | if (self && fd) { 208 | struct epoll_event event; 209 | event.events = fd->_events | EPOLLET; 210 | event.data.ptr = fd; 211 | return (0 == epoll_ctl (self->epoll_fd, 212 | EPOLL_CTL_ADD, fd->fd, &event)); 213 | } 214 | 215 | return false; 216 | } 217 | 218 | bool 219 | _hev_event_loop_del_fd (HevEventLoop *self, HevEventSourceFD *fd) 220 | { 221 | if (self && fd) { 222 | return (0 == epoll_ctl (self->epoll_fd, 223 | EPOLL_CTL_DEL, fd->fd, NULL)); 224 | } 225 | 226 | return false; 227 | } 228 | 229 | -------------------------------------------------------------------------------- /src/hev-event-loop.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-loop.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : An event loop 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_EVENT_LOOP_H__ 11 | #define __HEV_EVENT_LOOP_H__ 12 | 13 | typedef struct _HevEventLoop HevEventLoop; 14 | 15 | #include "hev-event-source.h" 16 | 17 | HevEventLoop * hev_event_loop_new (void); 18 | 19 | HevEventLoop * hev_event_loop_ref (HevEventLoop *self); 20 | void hev_event_loop_unref (HevEventLoop *self); 21 | 22 | void hev_event_loop_run (HevEventLoop *self); 23 | void hev_event_loop_quit (HevEventLoop *self); 24 | 25 | bool hev_event_loop_add_source (HevEventLoop *self, HevEventSource *source); 26 | bool hev_event_loop_del_source (HevEventLoop *self, HevEventSource *source); 27 | 28 | bool _hev_event_loop_add_fd (HevEventLoop *self, HevEventSourceFD *fd); 29 | bool _hev_event_loop_del_fd (HevEventLoop *self, HevEventSourceFD *fd); 30 | 31 | #endif /* __HEV_EVENT_LOOP_H__ */ 32 | 33 | -------------------------------------------------------------------------------- /src/hev-event-source-fd.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-fd.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : An event source FD 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-source.h" 11 | 12 | #ifndef __HEV_EVENT_SOURCE_FD_H__ 13 | #define __HEV_EVENT_SOURCE_FD_H__ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | typedef struct _HevEventSourceFD HevEventSourceFD; 20 | 21 | struct _HevEventSourceFD 22 | { 23 | int fd; 24 | uint32_t _events; 25 | uint32_t revents; 26 | unsigned int _ref_count; 27 | 28 | HevEventSource *source; 29 | void *data; 30 | }; 31 | 32 | static inline HevEventSourceFD * 33 | _hev_event_source_fd_new (HevEventSource *source, int fd, uint32_t events) 34 | { 35 | HevEventSourceFD *self = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevEventSourceFD)); 36 | if (self) { 37 | self->fd = fd; 38 | self->_events = events; 39 | self->revents = 0; 40 | self->_ref_count = 1; 41 | self->source = source; 42 | self->data = NULL; 43 | } 44 | 45 | return self; 46 | } 47 | 48 | static inline HevEventSourceFD * 49 | _hev_event_source_fd_ref (HevEventSourceFD *self) 50 | { 51 | if (self) { 52 | self->_ref_count ++; 53 | return self; 54 | } 55 | 56 | return NULL; 57 | } 58 | 59 | static inline void 60 | _hev_event_source_fd_unref (HevEventSourceFD *self) 61 | { 62 | if (self) { 63 | self->_ref_count --; 64 | if (0 == self->_ref_count) { 65 | HEV_MEMORY_ALLOCATOR_FREE (self); 66 | } 67 | } 68 | } 69 | 70 | static inline void 71 | hev_event_source_fd_set_data (HevEventSourceFD *self, void *data) 72 | { 73 | if (self) 74 | self->data = data; 75 | } 76 | 77 | static inline void * 78 | hev_event_source_fd_get_data (HevEventSourceFD *self) 79 | { 80 | return self ? self->data : NULL; 81 | } 82 | 83 | static inline void 84 | _hev_event_source_fd_clear_source (HevEventSourceFD *self) 85 | { 86 | if (self) 87 | self->source = NULL; 88 | } 89 | 90 | #endif /* __HEV_EVENT_SOURCE_H__ */ 91 | 92 | -------------------------------------------------------------------------------- /src/hev-event-source-fds.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-fds.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A fds event source 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-source-fds.h" 11 | 12 | static bool hev_event_source_fds_dispatch (HevEventSource *source, HevEventSourceFD *fd, 13 | HevEventSourceFunc callback, void *data); 14 | 15 | static HevEventSourceFuncs hev_event_source_fds_funcs = 16 | { 17 | .prepare = NULL, 18 | .check = NULL, 19 | .dispatch = hev_event_source_fds_dispatch, 20 | .finalize = NULL, 21 | }; 22 | 23 | HevEventSource * 24 | hev_event_source_fds_new (void) 25 | { 26 | return hev_event_source_new (&hev_event_source_fds_funcs, sizeof (HevEventSource)); 27 | } 28 | 29 | static bool 30 | hev_event_source_fds_dispatch (HevEventSource *source, HevEventSourceFD *fd, 31 | HevEventSourceFunc callback, void *data) 32 | { 33 | HevEventSourceFDsFunc _callback = (HevEventSourceFDsFunc) callback; 34 | return _callback (fd, data); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/hev-event-source-fds.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-fds.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A fds event source 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-source.h" 11 | 12 | #ifndef __HEV_EVENT_SOURCE_FDS_H__ 13 | #define __HEV_EVENT_SOURCE_FDS_H__ 14 | 15 | typedef struct _HevEventSourceFDs HevEventSourceFDs; 16 | typedef bool (*HevEventSourceFDsFunc) (HevEventSourceFD *fd, void *data); 17 | 18 | HevEventSource * hev_event_source_fds_new (void); 19 | 20 | #endif /* __HEV_EVENT_SOURCE_FDS_H__ */ 21 | 22 | -------------------------------------------------------------------------------- /src/hev-event-source-signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-signal.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A signal event source 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #if defined(ANDROID) 15 | #include 16 | #include 17 | #else /* GENERIC */ 18 | #include 19 | #endif 20 | 21 | #include "hev-event-source-signal.h" 22 | 23 | static bool hev_event_source_signal_check (HevEventSource *source, HevEventSourceFD *fd); 24 | static void hev_event_source_signal_finalize (HevEventSource *source); 25 | 26 | struct _HevEventSourceSignal 27 | { 28 | HevEventSource parent; 29 | 30 | int signal_fd; 31 | }; 32 | 33 | #if defined(ANDROID) 34 | #define SFD_NONBLOCK O_NONBLOCK 35 | 36 | struct signalfd_siginfo 37 | { 38 | uint32_t ssi_signo; 39 | int32_t ssi_errno; 40 | int32_t ssi_code; 41 | uint32_t ssi_pid; 42 | uint32_t ssi_uid; 43 | int32_t ssi_fd; 44 | uint32_t ssi_tid; 45 | uint32_t ssi_band; 46 | uint32_t ssi_overrun; 47 | uint32_t ssi_trapno; 48 | int32_t ssi_status; 49 | int32_t ssi_int; 50 | uint64_t ssi_ptr; 51 | uint64_t ssi_utime; 52 | uint64_t ssi_stime; 53 | uint64_t ssi_addr; 54 | uint8_t __pad[48]; 55 | }; 56 | #endif 57 | 58 | static HevEventSourceFuncs hev_event_source_signal_funcs = 59 | { 60 | .prepare = NULL, 61 | .check = hev_event_source_signal_check, 62 | .dispatch = NULL, 63 | .finalize = hev_event_source_signal_finalize, 64 | }; 65 | 66 | #if defined(ANDROID) 67 | static int 68 | signalfd (int fd, const sigset_t *mask, int flags) 69 | { 70 | return syscall (__NR_signalfd4, fd, mask, _NSIG / 8, flags); 71 | } 72 | #endif 73 | 74 | HevEventSource * 75 | hev_event_source_signal_new (int signal) 76 | { 77 | int fd = -1; 78 | HevEventSource *source = NULL; 79 | HevEventSourceSignal *self = NULL; 80 | sigset_t mask; 81 | 82 | sigemptyset (&mask); 83 | sigaddset (&mask, signal); 84 | sigprocmask(SIG_BLOCK, &mask, NULL); 85 | fd = signalfd (-1, &mask, SFD_NONBLOCK); 86 | if (-1 == fd) 87 | return NULL; 88 | 89 | source = hev_event_source_new (&hev_event_source_signal_funcs, 90 | sizeof (HevEventSourceSignal)); 91 | if (NULL == source) { 92 | close (fd); 93 | return NULL; 94 | } 95 | 96 | self = (HevEventSourceSignal *) source; 97 | self->signal_fd = fd; 98 | hev_event_source_add_fd (source, self->signal_fd, EPOLLIN | EPOLLET); 99 | 100 | return source; 101 | } 102 | 103 | static bool 104 | hev_event_source_signal_check (HevEventSource *source, HevEventSourceFD *fd) 105 | { 106 | HevEventSourceSignal *self = (HevEventSourceSignal *) source; 107 | if (EPOLLIN & fd->revents) { 108 | struct signalfd_siginfo siginfo; 109 | int size = read (self->signal_fd, &siginfo, sizeof (struct signalfd_siginfo)); 110 | if (-1 == size) { 111 | if (EAGAIN == errno) 112 | fd->revents &= ~EPOLLIN; 113 | return false; 114 | } 115 | return true; 116 | } 117 | 118 | return false; 119 | } 120 | 121 | static void 122 | hev_event_source_signal_finalize (HevEventSource *source) 123 | { 124 | HevEventSourceSignal *self = (HevEventSourceSignal *) source; 125 | close (self->signal_fd); 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/hev-event-source-signal.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-signal.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A signal event source 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-source.h" 11 | 12 | #ifndef __HEV_EVENT_SOURCE_SIGNAL_H__ 13 | #define __HEV_EVENT_SOURCE_SIGNAL_H__ 14 | 15 | typedef struct _HevEventSourceSignal HevEventSourceSignal; 16 | 17 | HevEventSource * hev_event_source_signal_new (int signal); 18 | 19 | #endif /* __HEV_EVENT_SOURCE_SIGNAL_H__ */ 20 | 21 | -------------------------------------------------------------------------------- /src/hev-event-source-timeout.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-timeout.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A timeout event source 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #if defined(ANDROID) 15 | #include 16 | #include 17 | #else /* GENERIC */ 18 | #include 19 | #endif 20 | 21 | #include "hev-event-source-timeout.h" 22 | 23 | #if defined(ANDROID) 24 | #define TFD_NONBLOCK O_NONBLOCK 25 | #define TFD_TIMER_ABSTIME 1 26 | #endif 27 | 28 | static bool hev_event_source_timeout_prepare (HevEventSource *source); 29 | static bool hev_event_source_timeout_check (HevEventSource *source, HevEventSourceFD *fd); 30 | static void hev_event_source_timeout_finalize (HevEventSource *source); 31 | 32 | struct _HevEventSourceTimeout 33 | { 34 | HevEventSource parent; 35 | 36 | int timer_fd; 37 | unsigned int interval; 38 | }; 39 | 40 | static HevEventSourceFuncs hev_event_source_timeout_funcs = 41 | { 42 | .prepare = hev_event_source_timeout_prepare, 43 | .check = hev_event_source_timeout_check, 44 | .dispatch = NULL, 45 | .finalize = hev_event_source_timeout_finalize, 46 | }; 47 | 48 | #if defined(ANDROID) 49 | static int 50 | timerfd_create (int clockid, int flags) 51 | { 52 | return syscall (__NR_timerfd_create, clockid, flags); 53 | } 54 | 55 | static int 56 | timerfd_settime (int fd, int flags, 57 | const struct itimerspec *new_value, 58 | struct itimerspec *old_value) 59 | { 60 | return syscall (__NR_timerfd_settime, fd, flags, new_value, old_value); 61 | } 62 | #endif 63 | 64 | HevEventSource * 65 | hev_event_source_timeout_new (unsigned int interval) 66 | { 67 | int fd = -1; 68 | HevEventSource *source = NULL; 69 | HevEventSourceTimeout *self = NULL; 70 | 71 | fd = timerfd_create (CLOCK_MONOTONIC, TFD_NONBLOCK); 72 | if (-1 == fd) 73 | return NULL; 74 | 75 | source = hev_event_source_new (&hev_event_source_timeout_funcs, 76 | sizeof (HevEventSourceTimeout)); 77 | if (NULL == source) { 78 | close (fd); 79 | return NULL; 80 | } 81 | 82 | self = (HevEventSourceTimeout *) source; 83 | self->timer_fd = fd; 84 | self->interval = interval; 85 | hev_event_source_add_fd (source, self->timer_fd, EPOLLIN | EPOLLET); 86 | 87 | return source; 88 | } 89 | 90 | static bool 91 | hev_event_source_timeout_prepare (HevEventSource *source) 92 | { 93 | HevEventSourceTimeout *self = (HevEventSourceTimeout *) source; 94 | struct itimerspec spec; 95 | 96 | spec.it_interval.tv_sec = 0; 97 | spec.it_interval.tv_nsec = 0; 98 | spec.it_value.tv_sec = self->interval / 1000; 99 | spec.it_value.tv_nsec = (self->interval % 1000) * 1000 * 1000; 100 | timerfd_settime (self->timer_fd, 0, &spec, NULL); 101 | 102 | return true; 103 | } 104 | 105 | static bool 106 | hev_event_source_timeout_check (HevEventSource *source, HevEventSourceFD *fd) 107 | { 108 | HevEventSourceTimeout *self = (HevEventSourceTimeout *) source; 109 | if (EPOLLIN & fd->revents) { 110 | uint64_t time; 111 | int size = read (self->timer_fd, &time, sizeof (uint64_t)); 112 | if (-1 == size) { 113 | if (EAGAIN == errno) 114 | fd->revents &= ~EPOLLIN; 115 | return false; 116 | } 117 | return true; 118 | } 119 | 120 | return false; 121 | } 122 | 123 | static void 124 | hev_event_source_timeout_finalize (HevEventSource *source) 125 | { 126 | HevEventSourceTimeout *self = (HevEventSourceTimeout *) source; 127 | close (self->timer_fd); 128 | } 129 | 130 | -------------------------------------------------------------------------------- /src/hev-event-source-timeout.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source-timeout.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : A timeout event source 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-source.h" 11 | 12 | #ifndef __HEV_EVENT_SOURCE_TIMEOUT_H__ 13 | #define __HEV_EVENT_SOURCE_TIMEOUT_H__ 14 | 15 | typedef struct _HevEventSourceTimeout HevEventSourceTimeout; 16 | 17 | HevEventSource * hev_event_source_timeout_new (unsigned int interval); 18 | 19 | #endif /* __HEV_EVENT_SOURCE_TIMEOUT_H__ */ 20 | 21 | -------------------------------------------------------------------------------- /src/hev-event-source.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : An event source 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "hev-event-source.h" 14 | 15 | static bool hev_event_source_prepare_default (HevEventSource *source); 16 | static bool hev_event_source_check_default (HevEventSource *source, HevEventSourceFD *fd); 17 | static bool hev_event_source_dispatch_default (HevEventSource *source, HevEventSourceFD *fd, 18 | HevEventSourceFunc callback, void *data); 19 | static void hev_event_source_finalize_default (HevEventSource *self); 20 | 21 | HevEventSource * 22 | hev_event_source_new (HevEventSourceFuncs *funcs, size_t struct_size) 23 | { 24 | if (sizeof (HevEventSource) <= struct_size) { 25 | HevEventSource *self = (HevEventSource *) HEV_MEMORY_ALLOCATOR_ALLOC (struct_size); 26 | if (self) { 27 | self->name = NULL; 28 | self->priority = 0; 29 | self->ref_count = 1; 30 | if (funcs) 31 | memcpy (&self->funcs, funcs, sizeof (HevEventSourceFuncs)); 32 | if (!self->funcs.prepare) 33 | self->funcs.prepare = hev_event_source_prepare_default; 34 | if (!self->funcs.check) 35 | self->funcs.check = hev_event_source_check_default; 36 | if (!self->funcs.dispatch) 37 | self->funcs.dispatch = hev_event_source_dispatch_default; 38 | if (!self->funcs.finalize) 39 | self->funcs.finalize = hev_event_source_finalize_default; 40 | self->callback.data = NULL; 41 | self->callback.callback = NULL; 42 | self->callback.notify = NULL; 43 | self->fds = NULL; 44 | self->loop = NULL; 45 | return self; 46 | } 47 | } 48 | 49 | return NULL; 50 | } 51 | 52 | HevEventSource * 53 | hev_event_source_ref (HevEventSource *self) 54 | { 55 | if (self) { 56 | self->ref_count ++; 57 | return self; 58 | } 59 | 60 | return NULL; 61 | } 62 | 63 | void 64 | hev_event_source_unref (HevEventSource *self) 65 | { 66 | if (self) { 67 | self->ref_count --; 68 | if (0 == self->ref_count) { 69 | HevSList *list = NULL; 70 | self->funcs.finalize (self); 71 | if (self->name) 72 | HEV_MEMORY_ALLOCATOR_FREE (self->name); 73 | if (self->callback.notify) 74 | self->callback.notify (self->callback.data); 75 | for (list=self->fds; list; list=hev_slist_next (list)) { 76 | _hev_event_source_fd_clear_source (hev_slist_data (list)); 77 | _hev_event_source_fd_unref (hev_slist_data (list)); 78 | } 79 | hev_slist_free (self->fds); 80 | HEV_MEMORY_ALLOCATOR_FREE (self); 81 | } 82 | } 83 | } 84 | 85 | void 86 | hev_event_source_set_name (HevEventSource *self, const char *name) 87 | { 88 | if (self && name) { 89 | if (self->name) 90 | HEV_MEMORY_ALLOCATOR_FREE (self->name); 91 | self->name = HEV_MEMORY_ALLOCATOR_ALLOC (strlen (name)); 92 | strcpy (self->name, name); 93 | } 94 | } 95 | 96 | const char * 97 | hev_event_source_get_name (HevEventSource *self) 98 | { 99 | return self ? self->name : NULL; 100 | } 101 | 102 | void 103 | hev_event_source_set_priority (HevEventSource *self, int priority) 104 | { 105 | if (self) 106 | self->priority = priority; 107 | } 108 | 109 | int 110 | hev_event_source_get_priority (HevEventSource *self) 111 | { 112 | return self ? self->priority : INT32_MAX; 113 | } 114 | 115 | void 116 | hev_event_source_set_callback (HevEventSource *self, HevEventSourceFunc callback, 117 | void *data, HevDestroyNotify notify) 118 | { 119 | if (self) { 120 | self->callback.data = data; 121 | self->callback.callback = callback; 122 | self->callback.notify = notify; 123 | } 124 | } 125 | 126 | HevEventSourceFD * 127 | hev_event_source_add_fd (HevEventSource *self, int fd, uint32_t events) 128 | { 129 | if (self) { 130 | HevSList *list = NULL; 131 | for (list=self->fds; list; list=hev_slist_next (list)) { 132 | HevEventSourceFD *efd = hev_slist_data (list); 133 | if (efd->fd == fd) 134 | return NULL; 135 | } 136 | HevEventSourceFD *efd = _hev_event_source_fd_new (self, fd, events); 137 | if (efd) { 138 | self->fds = hev_slist_append (self->fds, efd); 139 | if (self->loop && !_hev_event_loop_add_fd (self->loop, efd)) { 140 | _hev_event_source_fd_unref (efd); 141 | efd = NULL; 142 | } 143 | return efd; 144 | } 145 | } 146 | 147 | return NULL; 148 | } 149 | 150 | bool 151 | hev_event_source_del_fd (HevEventSource *self, int fd) 152 | { 153 | if (self) { 154 | HevSList *list = NULL; 155 | HevEventSourceFD *rfd = NULL; 156 | for (list=self->fds; list; list=hev_slist_next (list)) { 157 | HevEventSourceFD *efd = hev_slist_data (list); 158 | if (efd->fd == fd) { 159 | rfd = efd; 160 | break; 161 | } 162 | } 163 | if (rfd) { 164 | bool res = false; 165 | self->fds = hev_slist_remove (self->fds, rfd); 166 | if (self->loop) 167 | res = _hev_event_loop_del_fd (self->loop, rfd); 168 | _hev_event_source_fd_clear_source (rfd); 169 | _hev_event_source_fd_unref (rfd); 170 | return res; 171 | } 172 | } 173 | 174 | return false; 175 | } 176 | 177 | HevEventLoop * 178 | hev_event_source_get_loop (HevEventSource *self) 179 | { 180 | return self ? self->loop : NULL; 181 | } 182 | 183 | void 184 | _hev_event_source_set_loop (HevEventSource *self, HevEventLoop *loop) 185 | { 186 | if (self && (!self->loop) && loop) 187 | self->loop = loop; 188 | } 189 | 190 | static bool 191 | hev_event_source_prepare_default (HevEventSource *source) 192 | { 193 | return true; 194 | } 195 | 196 | static bool 197 | hev_event_source_check_default (HevEventSource *source, HevEventSourceFD *fd) 198 | { 199 | return true; 200 | } 201 | 202 | static bool 203 | hev_event_source_dispatch_default (HevEventSource *source, HevEventSourceFD *fd, 204 | HevEventSourceFunc callback, void *data) 205 | { 206 | if (callback) 207 | return callback (data); 208 | return true; 209 | } 210 | 211 | static void 212 | hev_event_source_finalize_default (HevEventSource *self) 213 | { 214 | } 215 | 216 | -------------------------------------------------------------------------------- /src/hev-event-source.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-event-source.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : An event source 7 | ============================================================================ 8 | */ 9 | 10 | #include "hev-event-loop.h" 11 | 12 | #ifndef __HEV_EVENT_SOURCE_H__ 13 | #define __HEV_EVENT_SOURCE_H__ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "hev-memory-allocator.h" 20 | #include "hev-slist.h" 21 | 22 | typedef struct _HevEventSource HevEventSource; 23 | typedef struct _HevEventSourceFuncs HevEventSourceFuncs; 24 | typedef bool (*HevEventSourceFunc) (void *data); 25 | 26 | #include "hev-event-source-fd.h" 27 | 28 | struct _HevEventSourceFuncs 29 | { 30 | bool (*prepare) (HevEventSource *self); 31 | bool (*check) (HevEventSource *self, HevEventSourceFD *fd); 32 | bool (*dispatch) (HevEventSource *self, HevEventSourceFD *fd, 33 | HevEventSourceFunc callback, void *data); 34 | void (*finalize) (HevEventSource *self); 35 | }; 36 | 37 | struct _HevEventSource 38 | { 39 | char *name; 40 | int priority; 41 | unsigned int ref_count; 42 | 43 | HevEventSourceFuncs funcs; 44 | struct { 45 | void *data; 46 | HevEventSourceFunc callback; 47 | HevDestroyNotify notify; 48 | } callback; 49 | 50 | HevSList *fds; 51 | HevEventLoop *loop; 52 | }; 53 | 54 | HevEventSource * hev_event_source_new (HevEventSourceFuncs *funcs, size_t struct_size); 55 | 56 | HevEventSource * hev_event_source_ref (HevEventSource *self); 57 | void hev_event_source_unref (HevEventSource *self); 58 | 59 | void hev_event_source_set_name (HevEventSource *self, const char *name); 60 | const char * hev_event_source_get_name (HevEventSource *self); 61 | 62 | void hev_event_source_set_priority (HevEventSource *self, int priority); 63 | int hev_event_source_get_priority (HevEventSource *self); 64 | 65 | void hev_event_source_set_callback (HevEventSource *self, HevEventSourceFunc callback, 66 | void *data, HevDestroyNotify notify); 67 | 68 | HevEventSourceFD * hev_event_source_add_fd (HevEventSource *self, int fd, uint32_t events); 69 | bool hev_event_source_del_fd (HevEventSource *self, int fd); 70 | 71 | HevEventLoop * hev_event_source_get_loop (HevEventSource *self); 72 | void _hev_event_source_set_loop (HevEventSource *self, HevEventLoop *loop); 73 | 74 | #endif /* __HEV_EVENT_SOURCE_H__ */ 75 | 76 | -------------------------------------------------------------------------------- /src/hev-main.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "hev-main.h" 16 | #include "hev-dns-forwarder.h" 17 | #include "hev-event-source-signal.h" 18 | 19 | static const char *default_dns_servers = "8.8.8.8:53"; 20 | static const char *default_dns_port = "53"; 21 | static const char *default_listen_addr = "0.0.0.0"; 22 | static const char *default_listen_port = "5300"; 23 | 24 | static void 25 | usage (const char *app) 26 | { 27 | printf ("\ 28 | usage: %s [-h] [-b BIND_ADDR] [-p BIND_PORT] [-s DNS]\n\ 29 | Forwarding DNS queries on TCP transport.\n\ 30 | \n\ 31 | -b BIND_ADDR address that listens, default: 0.0.0.0\n\ 32 | -p BIND_PORT port that listens, default: 5300\n\ 33 | -s DNS:[PORT] DNS servers to use, default: 8.8.8.8:53\n\ 34 | -h show this help message and exit\n", app); 35 | } 36 | 37 | static bool 38 | signal_handler (void *data) 39 | { 40 | HevEventLoop *loop = data; 41 | hev_event_loop_quit (loop); 42 | return false; 43 | } 44 | 45 | int 46 | main (int argc, char **argv) 47 | { 48 | HevEventLoop *loop = NULL; 49 | HevEventSource *source = NULL; 50 | HevDNSForwarder *forwarder = NULL; 51 | 52 | int ch; 53 | char *listen_addr = NULL; 54 | char *listen_port = NULL; 55 | char *dns_servers = NULL; 56 | char *dns_port = NULL; 57 | 58 | while ((ch = getopt(argc, argv, "hb:p:s:")) != -1) { 59 | switch (ch) { 60 | case 'h': 61 | usage(argv[0]); 62 | exit(0); 63 | case 'b': 64 | listen_addr = strdup(optarg); 65 | break; 66 | case 'p': 67 | listen_port = strdup(optarg); 68 | break; 69 | case 's': 70 | dns_servers = strdup(optarg); 71 | break; 72 | } 73 | } 74 | 75 | if (dns_servers == NULL) { 76 | dns_servers = strdup(default_dns_servers); 77 | } 78 | dns_port = strpbrk(dns_servers, ":#"); 79 | if (dns_port == NULL) { 80 | dns_port = strdup(default_dns_port); 81 | } else { 82 | *dns_port++ = '\0'; 83 | } 84 | if (listen_addr == NULL) { 85 | listen_addr = strdup(default_listen_addr); 86 | } 87 | if (listen_port == NULL) { 88 | listen_port = strdup(default_listen_port); 89 | } 90 | 91 | loop = hev_event_loop_new (); 92 | 93 | signal (SIGPIPE, SIG_IGN); 94 | 95 | source = hev_event_source_signal_new (SIGINT); 96 | hev_event_source_set_priority (source, 3); 97 | hev_event_source_set_callback (source, signal_handler, loop, NULL); 98 | hev_event_loop_add_source (loop, source); 99 | hev_event_source_unref (source); 100 | 101 | forwarder = hev_dns_forwarder_new (loop, listen_addr, listen_port, dns_servers, dns_port); 102 | if (forwarder) { 103 | hev_event_loop_run (loop); 104 | hev_dns_forwarder_unref (forwarder); 105 | } 106 | 107 | hev_event_loop_unref (loop); 108 | 109 | return 0; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /src/hev-main.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-main.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2014 everyone. 6 | Description : Main 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MAIN_H__ 11 | #define __HEV_MAIN_H__ 12 | 13 | #endif /* __HEV_MAIN_H__ */ 14 | 15 | -------------------------------------------------------------------------------- /src/hev-memory-allocator.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-memory-allocator.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Memory allocator 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include "hev-memory-allocator.h" 12 | 13 | HevMemoryAllocator * 14 | hev_memory_allocator_default (void) 15 | { 16 | static HevMemoryAllocator *allocator = NULL; 17 | 18 | if (!allocator) 19 | allocator = hev_memory_allocator_new (); 20 | 21 | return allocator; 22 | } 23 | 24 | HevMemoryAllocator * 25 | hev_memory_allocator_new (void) 26 | { 27 | HevMemoryAllocator *self = NULL; 28 | 29 | self = malloc (sizeof (HevMemoryAllocator)); 30 | if (self) 31 | self->ref_count = 1; 32 | 33 | return self; 34 | } 35 | 36 | HevMemoryAllocator * 37 | hev_memory_allocator_ref (HevMemoryAllocator *self) 38 | { 39 | if (self) { 40 | self->ref_count ++; 41 | return self; 42 | } 43 | 44 | return NULL; 45 | } 46 | 47 | void 48 | hev_memory_allocator_unref (HevMemoryAllocator *self) 49 | { 50 | if (self) { 51 | self->ref_count --; 52 | if (0 == self->ref_count) 53 | free (self); 54 | } 55 | } 56 | 57 | void * 58 | hev_memory_allocator_alloc (HevMemoryAllocator *self, size_t size) 59 | { 60 | return malloc (size); 61 | } 62 | 63 | void 64 | hev_memory_allocator_free (HevMemoryAllocator *self, void *ptr) 65 | { 66 | free (ptr); 67 | } 68 | 69 | void * 70 | hev_malloc (size_t size) 71 | { 72 | return HEV_MEMORY_ALLOCATOR_ALLOC (size); 73 | } 74 | 75 | void * 76 | hev_malloc0 (size_t size) 77 | { 78 | void *data = HEV_MEMORY_ALLOCATOR_ALLOC (size); 79 | if (data) 80 | memset (data, 0, size); 81 | return data; 82 | } 83 | 84 | void 85 | hev_free (void *ptr) 86 | { 87 | HEV_MEMORY_ALLOCATOR_FREE (ptr); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/hev-memory-allocator.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-memory-allocator.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Memory allocator 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_MEMORY_ALLOCATOR__ 11 | #define __HEV_MEMORY_ALLOCATOR__ 12 | 13 | #include 14 | 15 | #define HEV_MEMORY_ALLOCATOR_DEFAULT (hev_memory_allocator_default ()) 16 | #define HEV_MEMORY_ALLOCATOR_ALLOC(size) \ 17 | hev_memory_allocator_alloc (HEV_MEMORY_ALLOCATOR_DEFAULT, size) 18 | #define HEV_MEMORY_ALLOCATOR_FREE(ptr) \ 19 | hev_memory_allocator_free (HEV_MEMORY_ALLOCATOR_DEFAULT, ptr) 20 | 21 | typedef void (*HevDestroyNotify) (void *data); 22 | 23 | typedef struct _HevMemoryAllocator HevMemoryAllocator; 24 | 25 | struct _HevMemoryAllocator 26 | { 27 | unsigned int ref_count; 28 | }; 29 | 30 | HevMemoryAllocator * hev_memory_allocator_default (void); 31 | 32 | HevMemoryAllocator * hev_memory_allocator_new (void); 33 | 34 | HevMemoryAllocator * hev_memory_allocator_ref (HevMemoryAllocator *self); 35 | void hev_memory_allocator_unref (HevMemoryAllocator *self); 36 | 37 | void * hev_memory_allocator_alloc (HevMemoryAllocator *self, size_t size); 38 | void hev_memory_allocator_free (HevMemoryAllocator *self, void *ptr); 39 | 40 | void * hev_malloc (size_t size); 41 | void * hev_malloc0 (size_t size); 42 | void hev_free (void *ptr); 43 | 44 | #endif /* __HEV_MEMORY_ALLOCATOR__ */ 45 | 46 | -------------------------------------------------------------------------------- /src/hev-ring-buffer.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-ring-buffer.c 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Ring buffer data structure 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | #include "hev-ring-buffer.h" 14 | #include "hev-memory-allocator.h" 15 | 16 | struct _HevRingBuffer 17 | { 18 | uint8_t *buffer; 19 | unsigned int ref_count; 20 | 21 | size_t wp; 22 | size_t rp; 23 | size_t len; 24 | bool full; 25 | }; 26 | 27 | HevRingBuffer * 28 | hev_ring_buffer_new (size_t len) 29 | { 30 | HevRingBuffer *self = NULL; 31 | self = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevRingBuffer) + len); 32 | if (self) { 33 | self->ref_count = 1; 34 | self->wp = 0; 35 | self->rp = 0; 36 | self->len = len; 37 | self->full = false; 38 | self->buffer = ((void *) self) + sizeof (HevRingBuffer); 39 | } 40 | 41 | return self; 42 | } 43 | 44 | HevRingBuffer * 45 | hev_ring_buffer_ref (HevRingBuffer *self) 46 | { 47 | if (self) 48 | self->ref_count ++; 49 | 50 | return self; 51 | } 52 | 53 | void 54 | hev_ring_buffer_unref (HevRingBuffer *self) 55 | { 56 | if (self) { 57 | self->ref_count --; 58 | if (0 == self->ref_count) 59 | HEV_MEMORY_ALLOCATOR_FREE (self); 60 | } 61 | } 62 | 63 | void 64 | hev_ring_buffer_reset (HevRingBuffer *self) 65 | { 66 | if (self) { 67 | self->wp = 0; 68 | self->rp = 0; 69 | self->full = false; 70 | } 71 | } 72 | 73 | size_t 74 | hev_ring_buffer_reading (HevRingBuffer *self, struct iovec *iovec) 75 | { 76 | if (self && iovec) { 77 | if (0 == self->rp) { 78 | /* rp 79 | * ||--------------------|| 80 | * wp */ 81 | if ((self->rp == self->wp) && self->full) { 82 | iovec[0].iov_base = self->buffer; 83 | iovec[0].iov_len = self->len; 84 | return 1; 85 | } 86 | /* rp 87 | * ||--------------------|| 88 | * wp */ 89 | if ((0 < self->wp) && (self->len > self->wp)) { 90 | iovec[0].iov_base = self->buffer; 91 | iovec[0].iov_len = self->wp; 92 | return 1; 93 | } 94 | /* rp 95 | * ||--------------------|| 96 | * wp */ 97 | if (self->len == self->wp) { 98 | iovec[0].iov_base = self->buffer; 99 | iovec[0].iov_len = self->wp; 100 | return 1; 101 | } 102 | } 103 | if ((0 < self->rp) && (self->len > self->rp)) { 104 | /* rp 105 | * ||--------------------|| 106 | * wp */ 107 | if (0 == self->wp) { 108 | iovec[0].iov_base = self->buffer + self->rp; 109 | iovec[0].iov_len = self->len - self->rp; 110 | return 1; 111 | } 112 | /* rp 113 | * ||--------------------|| 114 | * wp */ 115 | if ((0 < self->wp) && (self->wp < self->rp)) { 116 | iovec[0].iov_base = self->buffer + self->rp; 117 | iovec[0].iov_len = self->len - self->rp; 118 | iovec[1].iov_base = self->buffer; 119 | iovec[1].iov_len = self->wp; 120 | return 2; 121 | } 122 | /* rp 123 | * ||--------------------|| 124 | * wp */ 125 | if ((self->wp == self->rp) && self->full) { 126 | iovec[0].iov_base = self->buffer + self->rp; 127 | iovec[0].iov_len = self->len - self->rp; 128 | iovec[1].iov_base = self->buffer; 129 | iovec[1].iov_len = self->wp; 130 | return 2; 131 | } 132 | /* rp 133 | * ||--------------------|| 134 | * wp */ 135 | if ((self->wp > self->rp) && (self->wp < self->len)) { 136 | iovec[0].iov_base = self->buffer + self->rp; 137 | iovec[0].iov_len = self->wp - self->rp; 138 | return 1; 139 | } 140 | /* rp 141 | * ||--------------------|| 142 | * wp */ 143 | if (self->len == self->wp) { 144 | iovec[0].iov_base = self->buffer + self->rp; 145 | iovec[0].iov_len = self->wp - self->rp; 146 | return 1; 147 | } 148 | } 149 | if (self->len == self->rp) { 150 | /* rp 151 | * ||--------------------|| 152 | * wp */ 153 | if (0 == self->wp) { 154 | return 0; 155 | } 156 | 157 | /* rp 158 | * ||--------------------|| 159 | * wp */ 160 | if ((0 < self->wp) && (self->wp < self->len)) { 161 | iovec[0].iov_base = self->buffer; 162 | iovec[0].iov_len = self->wp; 163 | return 1; 164 | } 165 | 166 | /* rp 167 | * ||--------------------|| 168 | * wp */ 169 | if ((self->wp == self->rp) && self->full) { 170 | iovec[0].iov_base = self->buffer; 171 | iovec[0].iov_len = self->wp; 172 | return 1; 173 | } 174 | } 175 | } 176 | 177 | return 0; 178 | } 179 | 180 | void 181 | hev_ring_buffer_read_finish (HevRingBuffer *self, size_t inc_len) 182 | { 183 | if (self && (0 < inc_len)) { 184 | if (0 == self->rp) { 185 | /* rp 186 | * ||--------------------|| 187 | * wp */ 188 | if ((self->rp == self->wp) && self->full) { 189 | assert (self->len >= inc_len); 190 | self->rp = inc_len; 191 | self->full = false; 192 | return; 193 | } 194 | /* rp 195 | * ||--------------------|| 196 | * wp */ 197 | if ((0 < self->wp) && (self->len > self->wp)) { 198 | assert (self->wp >= inc_len); 199 | self->rp = inc_len; 200 | return; 201 | } 202 | /* rp 203 | * ||--------------------|| 204 | * wp */ 205 | if (self->len == self->wp) { 206 | assert (self->len >= inc_len); 207 | self->rp = inc_len; 208 | return; 209 | } 210 | } 211 | if ((0 < self->rp) && (self->len > self->rp)) { 212 | /* rp 213 | * ||--------------------|| 214 | * wp */ 215 | if (0 == self->wp) { 216 | assert ((self->len - self->rp) >= inc_len); 217 | self->rp += inc_len; 218 | return; 219 | } 220 | /* rp 221 | * ||--------------------|| 222 | * wp */ 223 | if ((0 < self->wp) && (self->wp < self->rp)) { 224 | assert ((self->len - self->rp + self->wp) >= inc_len); 225 | self->rp += inc_len; 226 | if (self->rp > self->len) 227 | self->rp -= self->len; 228 | return; 229 | } 230 | /* rp 231 | * ||--------------------|| 232 | * wp */ 233 | if ((self->wp == self->rp) && self->full) { 234 | assert ((self->len - self->rp + self->wp) >= inc_len); 235 | self->rp += inc_len; 236 | if (self->rp > self->len) 237 | self->rp -= self->len; 238 | self->full = false; 239 | return; 240 | } 241 | /* rp 242 | * ||--------------------|| 243 | * wp */ 244 | if ((self->wp > self->rp) && (self->wp < self->len)) { 245 | assert ((self->wp - self->rp) >= inc_len); 246 | self->rp += inc_len; 247 | return; 248 | } 249 | /* rp 250 | * ||--------------------|| 251 | * wp */ 252 | if (self->len == self->wp) { 253 | assert ((self->wp - self->rp) >= inc_len); 254 | self->rp += inc_len; 255 | return; 256 | } 257 | } 258 | if (self->len == self->rp) { 259 | /* rp 260 | * ||--------------------|| 261 | * wp */ 262 | if (0 == self->wp) { 263 | return; 264 | } 265 | 266 | /* rp 267 | * ||--------------------|| 268 | * wp */ 269 | if ((0 < self->wp) && (self->wp < self->len)) { 270 | assert (self->wp >= inc_len); 271 | self->rp = inc_len; 272 | return; 273 | } 274 | 275 | /* rp 276 | * ||--------------------|| 277 | * wp */ 278 | if ((self->wp == self->rp) && self->full) { 279 | assert (self->wp >= inc_len); 280 | self->rp = inc_len; 281 | self->full = false; 282 | return; 283 | } 284 | } 285 | } 286 | } 287 | 288 | size_t 289 | hev_ring_buffer_writing (HevRingBuffer *self, struct iovec *iovec) 290 | { 291 | if (self && iovec) { 292 | if (0 == self->rp) { 293 | /* rp 294 | * ||--------------------|| 295 | * wp */ 296 | if ((self->rp == self->wp) && !self->full) { 297 | iovec[0].iov_base = self->buffer; 298 | iovec[0].iov_len = self->len; 299 | return 1; 300 | } 301 | /* rp 302 | * ||--------------------|| 303 | * wp */ 304 | if ((0 < self->wp) && (self->len > self->wp)) { 305 | iovec[0].iov_base = self->buffer + self->wp; 306 | iovec[0].iov_len = self->len - self->wp; 307 | return 1; 308 | } 309 | /* rp 310 | * ||--------------------|| 311 | * wp */ 312 | if (self->len == self->wp) { 313 | return 0; 314 | } 315 | } 316 | if ((0 < self->rp) && (self->len > self->rp)) { 317 | /* rp 318 | * ||--------------------|| 319 | * wp */ 320 | if (0 == self->wp) { 321 | iovec[0].iov_base = self->buffer; 322 | iovec[0].iov_len = self->rp - self->wp; 323 | return 1; 324 | } 325 | /* rp 326 | * ||--------------------|| 327 | * wp */ 328 | if ((0 < self->wp) && (self->wp < self->rp)) { 329 | iovec[0].iov_base = self->buffer + self->wp; 330 | iovec[0].iov_len = self->rp - self->wp; 331 | return 1; 332 | } 333 | /* rp 334 | * ||--------------------|| 335 | * wp */ 336 | if ((self->wp == self->rp) && !self->full) { 337 | iovec[0].iov_base = self->buffer + self->wp; 338 | iovec[0].iov_len = self->len - self->wp; 339 | iovec[1].iov_base = self->buffer; 340 | iovec[1].iov_len = self->rp; 341 | return 2; 342 | } 343 | /* rp 344 | * ||--------------------|| 345 | * wp */ 346 | if ((self->wp > self->rp) && (self->wp < self->len)) { 347 | iovec[0].iov_base = self->buffer + self->wp; 348 | iovec[0].iov_len = self->len - self->wp; 349 | iovec[1].iov_base = self->buffer; 350 | iovec[1].iov_len = self->rp; 351 | return 2; 352 | } 353 | /* rp 354 | * ||--------------------|| 355 | * wp */ 356 | if (self->len == self->wp) { 357 | iovec[0].iov_base = self->buffer; 358 | iovec[0].iov_len = self->rp; 359 | return 1; 360 | } 361 | } 362 | if (self->len == self->rp) { 363 | /* rp 364 | * ||--------------------|| 365 | * wp */ 366 | if (0 == self->wp) { 367 | iovec[0].iov_base = self->buffer; 368 | iovec[0].iov_len = self->rp; 369 | return 1; 370 | } 371 | 372 | /* rp 373 | * ||--------------------|| 374 | * wp */ 375 | if ((0 < self->wp) && (self->wp < self->len)) { 376 | iovec[0].iov_base = self->buffer + self->wp; 377 | iovec[0].iov_len = self->rp - self->wp; 378 | return 1; 379 | } 380 | 381 | /* rp 382 | * ||--------------------|| 383 | * wp */ 384 | if ((self->wp == self->rp) && !self->full) { 385 | iovec[0].iov_base = self->buffer; 386 | iovec[0].iov_len = self->rp; 387 | return 1; 388 | } 389 | } 390 | } 391 | 392 | return 0; 393 | } 394 | 395 | void 396 | hev_ring_buffer_write_finish (HevRingBuffer *self, size_t inc_len) 397 | { 398 | if (self && (0 < inc_len)) { 399 | if (0 == self->rp) { 400 | /* rp 401 | * ||--------------------|| 402 | * wp */ 403 | if ((self->rp == self->wp) && !self->full) { 404 | assert (self->len >= inc_len); 405 | self->wp = inc_len; 406 | return; 407 | } 408 | /* rp 409 | * ||--------------------|| 410 | * wp */ 411 | if ((0 < self->wp) && (self->len > self->wp)) { 412 | assert ((self->len - self->wp) >= inc_len); 413 | self->wp += inc_len; 414 | return; 415 | } 416 | /* rp 417 | * ||--------------------|| 418 | * wp */ 419 | if (self->len == self->wp) { 420 | return; 421 | } 422 | } 423 | if ((0 < self->rp) && (self->len > self->rp)) { 424 | /* rp 425 | * ||--------------------|| 426 | * wp */ 427 | if (0 == self->wp) { 428 | assert (self->rp >= inc_len); 429 | self->wp += inc_len; 430 | if (self->wp == self->rp) 431 | self->full = true; 432 | return; 433 | } 434 | /* rp 435 | * ||--------------------|| 436 | * wp */ 437 | if ((0 < self->wp) && (self->wp < self->rp)) { 438 | assert ((self->rp - self->wp) >= inc_len); 439 | self->wp += inc_len; 440 | if (self->wp == self->rp) 441 | self->full = true; 442 | return; 443 | } 444 | /* rp 445 | * ||--------------------|| 446 | * wp */ 447 | if ((self->wp == self->rp) && !self->full) { 448 | assert (self->len >= inc_len); 449 | self->wp += inc_len; 450 | if (self->wp > self->len) 451 | self->wp -= self->len; 452 | if (self->len == inc_len) 453 | self->full = true; 454 | return; 455 | } 456 | /* rp 457 | * ||--------------------|| 458 | * wp */ 459 | if ((self->wp > self->rp) && (self->wp < self->len)) { 460 | assert ((self->len - self->wp + self->rp) >= inc_len); 461 | self->wp += inc_len; 462 | if (self->wp > self->len) 463 | self->wp -= self->len; 464 | if (self->wp == self->rp) 465 | self->full = true; 466 | return; 467 | } 468 | /* rp 469 | * ||--------------------|| 470 | * wp */ 471 | if (self->len == self->wp) { 472 | assert (self->rp >= inc_len); 473 | self->wp = inc_len; 474 | if (self->wp == self->rp) 475 | self->full = true; 476 | return; 477 | } 478 | } 479 | if (self->len == self->rp) { 480 | /* rp 481 | * ||--------------------|| 482 | * wp */ 483 | if (0 == self->wp) { 484 | assert (self->rp >= inc_len); 485 | self->wp = inc_len; 486 | if (self->wp == self->rp) 487 | self->full = true; 488 | return; 489 | } 490 | 491 | /* rp 492 | * ||--------------------|| 493 | * wp */ 494 | if ((0 < self->wp) && (self->wp < self->len)) { 495 | assert ((self->len - self->wp) >= inc_len); 496 | self->wp += inc_len; 497 | if (self->wp == self->rp) 498 | self->full = true; 499 | return; 500 | } 501 | 502 | /* rp 503 | * ||--------------------|| 504 | * wp */ 505 | if ((self->wp == self->rp) && !self->full) { 506 | assert (self->len >= inc_len); 507 | self->wp = inc_len; 508 | if (self->len == inc_len) 509 | self->full = true; 510 | return; 511 | } 512 | } 513 | } 514 | } 515 | 516 | -------------------------------------------------------------------------------- /src/hev-ring-buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-ring-buffer.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Ring buffer data structure 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_RING_BUFFER_H__ 11 | #define __HEV_RING_BUFFER_H__ 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | typedef struct _HevRingBuffer HevRingBuffer; 18 | 19 | HevRingBuffer * hev_ring_buffer_new (size_t len); 20 | 21 | HevRingBuffer * hev_ring_buffer_ref (HevRingBuffer *self); 22 | void hev_ring_buffer_unref (HevRingBuffer *self); 23 | 24 | void hev_ring_buffer_reset (HevRingBuffer *self); 25 | 26 | size_t hev_ring_buffer_reading (HevRingBuffer *self, struct iovec *iovec); 27 | void hev_ring_buffer_read_finish (HevRingBuffer *self, size_t inc_len); 28 | 29 | size_t hev_ring_buffer_writing (HevRingBuffer *self, struct iovec *iovec); 30 | void hev_ring_buffer_write_finish (HevRingBuffer *self, size_t inc_len); 31 | 32 | #endif /* __HEV_RING_BUFFER_H__ */ 33 | 34 | -------------------------------------------------------------------------------- /src/hev-slist.c: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-slist.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Singly-linked list data structure 7 | ============================================================================ 8 | */ 9 | 10 | #include 11 | 12 | #include "hev-slist.h" 13 | #include "hev-memory-allocator.h" 14 | 15 | struct _HevSList 16 | { 17 | void *data; 18 | HevSList *next; 19 | }; 20 | 21 | HevSList * 22 | hev_slist_append (HevSList *self, void *data) 23 | { 24 | HevSList *new = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevSList)); 25 | if (new) { 26 | new->data = data; 27 | new->next = NULL; 28 | if (self) { 29 | HevSList *last = hev_slist_last (self); 30 | last->next = new; 31 | return self; 32 | } else { 33 | return new; 34 | } 35 | } 36 | 37 | return NULL; 38 | } 39 | 40 | HevSList * 41 | hev_slist_prepend (HevSList *self, void *data) 42 | { 43 | HevSList *new = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevSList)); 44 | if (new) { 45 | new->data = data; 46 | if (self) { 47 | new->next = self; 48 | } else { 49 | new->next = NULL; 50 | } 51 | return new; 52 | } 53 | 54 | return NULL; 55 | } 56 | 57 | HevSList * 58 | hev_slist_insert (HevSList *self, void *data, unsigned int position) 59 | { 60 | HevSList *new = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevSList)); 61 | if (new) { 62 | new->data = data; 63 | if (self) { 64 | HevSList *node = NULL, *prev = NULL, *last = NULL; 65 | unsigned int i = 0; 66 | for (node=self; node; prev=node,node=node->next,i++) { 67 | if (i == position) 68 | break; 69 | last = node; 70 | } 71 | if (node) { 72 | new->next = node; 73 | if (prev) 74 | prev->next = new; 75 | else 76 | self = new; 77 | } else { 78 | new->next = NULL; 79 | last->next = new; 80 | } 81 | return self; 82 | } else { 83 | new->next = NULL; 84 | return new; 85 | } 86 | } 87 | 88 | return NULL; 89 | } 90 | 91 | HevSList * 92 | hev_slist_insert_before (HevSList *self, void *data, HevSList *sibling) 93 | { 94 | HevSList *new = HEV_MEMORY_ALLOCATOR_ALLOC (sizeof (HevSList)); 95 | if (new) { 96 | new->data = data; 97 | if (self) { 98 | HevSList *node = NULL, *prev = NULL, *last = NULL; 99 | for (node=self; node; prev=node,node=node->next) { 100 | if (node == sibling) 101 | break; 102 | last = node; 103 | } 104 | if (node) { 105 | new->next = node; 106 | if (prev) 107 | prev->next = new; 108 | else 109 | self = new; 110 | } else { 111 | new->next = NULL; 112 | last->next = new; 113 | } 114 | return self; 115 | } else { 116 | new->next = NULL; 117 | return new; 118 | } 119 | } 120 | 121 | return NULL; 122 | } 123 | 124 | HevSList * 125 | hev_slist_remove (HevSList *self, const void *data) 126 | { 127 | if (self) { 128 | HevSList *node = NULL, *prev = NULL; 129 | for (node=self; node; prev=node,node=node->next) { 130 | if (data == node->data) { 131 | if (prev) 132 | prev->next = node->next; 133 | else 134 | self = node->next; 135 | HEV_MEMORY_ALLOCATOR_FREE (node); 136 | break; 137 | } 138 | } 139 | return self; 140 | } 141 | 142 | return NULL; 143 | } 144 | 145 | HevSList * 146 | hev_slist_remove_all (HevSList *self, const void *data) 147 | { 148 | if (self) { 149 | HevSList *node = NULL, *prev = NULL; 150 | for (node=self; node;) { 151 | HevSList *curr = node; 152 | node = node->next; 153 | if (data == curr->data) { 154 | if (prev) 155 | prev->next = curr->next; 156 | else 157 | self = curr->next; 158 | HEV_MEMORY_ALLOCATOR_FREE (curr); 159 | } else { 160 | prev = curr; 161 | } 162 | } 163 | return self; 164 | } 165 | 166 | return NULL; 167 | } 168 | 169 | HevSList * 170 | hev_slist_last (HevSList *self) 171 | { 172 | if (self) { 173 | while (self->next) 174 | self = self->next; 175 | } 176 | 177 | return self; 178 | } 179 | 180 | HevSList * 181 | hev_slist_next (HevSList *self) 182 | { 183 | if (self) 184 | return self->next; 185 | 186 | return NULL; 187 | } 188 | 189 | unsigned int 190 | hev_slist_length (HevSList *self) 191 | { 192 | if (self) { 193 | HevSList *node = NULL; 194 | unsigned int count = 0; 195 | for (node=self; node; node=node->next) 196 | count ++; 197 | return count; 198 | } 199 | 200 | return 0; 201 | } 202 | 203 | void 204 | hev_slist_free (HevSList *self) 205 | { 206 | if (self) { 207 | HevSList *node = NULL; 208 | for (node=self; node;) { 209 | HevSList *curr = node; 210 | node = node->next; 211 | HEV_MEMORY_ALLOCATOR_FREE (curr); 212 | } 213 | } 214 | } 215 | 216 | -------------------------------------------------------------------------------- /src/hev-slist.h: -------------------------------------------------------------------------------- 1 | /* 2 | ============================================================================ 3 | Name : hev-slist.h 4 | Author : Heiher 5 | Copyright : Copyright (c) 2013 everyone. 6 | Description : Singly-linked list data structure 7 | ============================================================================ 8 | */ 9 | 10 | #ifndef __HEV_SLIST_H__ 11 | #define __HEV_SLIST_H__ 12 | 13 | typedef struct _HevSList HevSList; 14 | 15 | HevSList * hev_slist_append (HevSList *self, void *data); 16 | HevSList * hev_slist_prepend (HevSList *self, void *data); 17 | HevSList * hev_slist_insert (HevSList *self, void *data, unsigned int position); 18 | HevSList * hev_slist_insert_before (HevSList *self, void *data, HevSList *sibling); 19 | HevSList * hev_slist_remove (HevSList *self, const void *data); 20 | HevSList * hev_slist_remove_all (HevSList *self, const void *data); 21 | 22 | HevSList * hev_slist_last (HevSList *self); 23 | HevSList * hev_slist_next (HevSList *self); 24 | 25 | static inline void * 26 | hev_slist_data (HevSList *self) 27 | { 28 | return self ? *((void **) self) : NULL; 29 | } 30 | 31 | static inline void 32 | hev_slist_set_data (HevSList *self, void *data) 33 | { 34 | if (self) 35 | *((void **) self) = data; 36 | } 37 | 38 | unsigned int hev_slist_length (HevSList *self); 39 | 40 | void hev_slist_free (HevSList *self); 41 | 42 | #endif /* __HEV_SLIST_H__ */ 43 | 44 | --------------------------------------------------------------------------------