Line data Source code
1 : #include <minipot_session.h> 2 : #include <minipot_utils.h> 3 : #include <arpa/inet.h> 4 : #include <unistd.h> 5 : #include "log.h" 6 : 7 0 : static int sockaddr2str(const struct sockaddr_storage *sockaddr, char *buff) { 8 0 : if (sockaddr->ss_family == AF_INET6) { 9 : // IPv6 10 0 : const struct sockaddr_in6 *ip_v6_sockaddr = 11 : (const struct sockaddr_in6 *)sockaddr; 12 0 : const struct in6_addr *addr = &(ip_v6_sockaddr->sin6_addr); 13 0 : if (addr->s6_addr32[0] == 0 && addr->s6_addr32[1] == 0 && 14 0 : addr->s6_addr16[4] == 0 && addr->s6_addr16[5] == 0xFFFF) 15 : // IPv4 mapped on IPv6 address with format 0:0:FFFF:<IPv4-address> 16 0 : inet_ntop(AF_INET, &addr->s6_addr32[3], buff, INET_ADDRSTRLEN); 17 : else 18 : // normal IPv6 address 19 0 : inet_ntop(AF_INET6, addr, buff, INET6_ADDRSTRLEN); 20 0 : } else if (sockaddr->ss_family == AF_INET) { 21 : // IPv4 22 0 : const struct sockaddr_in *ip_v4_sockaddr = 23 : (const struct sockaddr_in *)sockaddr; 24 0 : inet_ntop(AF_INET, &ip_v4_sockaddr->sin_addr, buff, INET_ADDRSTRLEN); 25 : } else { 26 0 : error("Couldn't get IP adress from unsupported socket family type: %d", 27 : sockaddr->ss_family); 28 0 : return -1; 29 : } 30 : return 0; 31 : } 32 : 33 : void minipot_session_init(struct minipot_session *self) { 34 0 : self->read_ev = event_new(NULL, 0, 0, NULL, NULL); 35 0 : assert(self->read_ev); 36 0 : self->fd = -1; 37 0 : } 38 : 39 : void minipot_session_destroy(struct minipot_session *self) { 40 0 : event_free(self->read_ev); 41 0 : } 42 : 43 : int minipot_session_accept(struct minipot_session *self, int accept_fd, 44 : struct event_base *ev_base, event_callback_fn read_cb, void *read_cb_arg) { 45 0 : struct sockaddr_storage conn_addr; 46 0 : socklen_t conn_addr_len = sizeof(conn_addr); 47 0 : self->fd = accept(accept_fd, (struct sockaddr *)&conn_addr, 48 : &conn_addr_len); 49 0 : if (self->fd < 0) 50 : return -1; 51 0 : if (minipot_set_nonblock(self->fd)) 52 0 : goto err; 53 0 : if (sockaddr2str(&conn_addr, self->ip_addr)) 54 0 : goto err; 55 : // now we can assign read event as we know the FD 56 0 : if (event_assign(self->read_ev, ev_base, self->fd, EV_READ | EV_PERSIST, 57 : read_cb, read_cb_arg)) 58 0 : goto err; 59 0 : if (event_add(self->read_ev, NULL)) 60 0 : goto err; 61 : return 0; 62 0 : err: 63 0 : minipot_session_close(self); 64 0 : return -1; 65 : } 66 : 67 : void minipot_session_close(struct minipot_session *self) { 68 0 : close(self->fd); 69 0 : self->fd = -1; 70 0 : event_del(self->read_ev); 71 0 : } 72 : 73 : bool minipot_session_is_available(struct minipot_session *self) { 74 0 : return self->fd == -1; 75 : }