INTERPOSE (accept, int, int sockfd, struct sockaddr * addr, socklen_t * addrlen) { v4v_addr_t peer; int ret; CHECK_INTERPOSE (accept); if (!is_our_fd (sockfd)) return orig_accept (sockfd, addr, addrlen); ret = v4v_accept (sockfd, &peer); register_fd (ret); if (is_our_af (sockfd)) { v4v_map_v4va_to_sxenv4v (addr, addrlen, &peer); } else { v4v_map_v4va_to_sin (addr, addrlen, &peer); } return ret; }
INTERPOSE (socket, int, int domain, int type, int protocol) { int ret; CHECK_INTERPOSE (socket); if ((domain != PF_XENV4V) && (domain != PF_INETV4V) && ((domain != PF_INET) || (!getenv ("INET_IS_V4V"))) && !force_xen) return orig_socket (domain, type, protocol); ret = v4v_socket (type); if (ret < 0) return ret; register_fd (ret); if (domain == PF_XENV4V) register_af (ret); else unregister_af (ret); return ret; }
int win32_open_ex(void *x, const char *filename, int oflag, struct stat *buffer) { int fd; struct stat _buffer; if (NULL == buffer) { buffer = &_buffer; } if (0 != stat(filename, buffer)) { return -1; } if (S_ISDIR(buffer->st_mode)) { if (!register_fd(x, &fd, filename)) { return -1; } } else { if (-1 == (fd = _open(filename, _O_RDONLY))) { return -1; } } return fd; }
int tcp_accept(struct tcp_sock *m) { int ret; /* we got an attempt to connect but we already have a client? */ if (m->state != TCP_SERVER_ACCEPTING) { /* clear the session and restart ... */ unregister_fd(m->client_fd, STATE(fds)); close(m->client_fd); m->client_fd = -1; m->state = TCP_SERVER_ACCEPTING; } /* the other peer wants to connect ... */ ret = accept(m->fd, NULL, NULL); if (ret == -1) { if (errno != EAGAIN) { /* unexpected error. Give us another try. */ m->state = TCP_SERVER_ACCEPTING; } else { /* waiting for new connections. */ m->state = TCP_SERVER_ACCEPTING; } } else { /* the peer finally got connected. */ if (fcntl(ret, F_SETFL, O_NONBLOCK) == -1) { /* close the connection and give us another chance. */ close(ret); return -1; } m->client_fd = ret; m->state = TCP_SERVER_CONNECTED; register_fd(m->client_fd, STATE(fds)); } return m->client_fd; }
struct tcp_sock *tcp_server_create(struct tcp_conf *c) { int yes = 1, ret; struct tcp_sock *m; socklen_t socklen = sizeof(int); m = calloc(sizeof(struct tcp_sock), 1); if (m == NULL) return NULL; m->conf = c; switch(c->ipproto) { case AF_INET: m->addr.ipv4.sin_family = AF_INET; m->addr.ipv4.sin_port = htons(c->port); m->addr.ipv4.sin_addr = c->server.ipv4.inet_addr; m->sockaddr_len = sizeof(struct sockaddr_in); break; case AF_INET6: m->addr.ipv6.sin6_family = AF_INET6; m->addr.ipv6.sin6_port = htons(c->port); m->addr.ipv6.sin6_addr = c->server.ipv6.inet_addr6; m->addr.ipv6.sin6_scope_id = c->server.ipv6.scope_id; m->sockaddr_len = sizeof(struct sockaddr_in6); break; } m->fd = socket(c->ipproto, SOCK_STREAM, 0); if (m->fd == -1) { free(m); return NULL; } if (setsockopt(m->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { close(m->fd); free(m); return NULL; } if (setsockopt(m->fd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int)) == -1) { close(m->fd); free(m); return NULL; } #ifndef SO_RCVBUFFORCE #define SO_RCVBUFFORCE 33 #endif if (c->rcvbuf && setsockopt(m->fd, SOL_SOCKET, SO_RCVBUFFORCE, &c->rcvbuf, sizeof(int)) == -1) { /* not supported in linux kernel < 2.6.14 */ if (errno != ENOPROTOOPT) { close(m->fd); free(m); return NULL; } } getsockopt(m->fd, SOL_SOCKET, SO_RCVBUF, &c->rcvbuf, &socklen); if (bind(m->fd, (struct sockaddr *) &m->addr, m->sockaddr_len) == -1) { close(m->fd); free(m); return NULL; } if (listen(m->fd, 1) == -1) { close(m->fd); free(m); return NULL; } if (fcntl(m->fd, F_SETFL, O_NONBLOCK) == -1) { close(m->fd); free(m); return NULL; } /* now we accept new connections ... */ ret = accept(m->fd, NULL, NULL); if (ret == -1) { if (errno != EAGAIN) { /* unexpected error, give up. */ close(m->fd); free(m); m = NULL; } else { /* still in progress ... we'll do it in tcp_recv() */ m->state = TCP_SERVER_ACCEPTING; } } else { /* very unlikely at this stage. */ if (fcntl(ret, F_SETFL, O_NONBLOCK) == -1) { /* unexpected error, give up. */ close(m->fd); free(m); return NULL; } m->client_fd = ret; m->state = TCP_SERVER_CONNECTED; register_fd(m->client_fd, STATE(fds)); } return m; }