예제 #1
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                                struct sockaddr *src_addr, socklen_t *addrlen)
{
    int ret;
    ssize_t n;

    while ((n = g_sys_recvfrom(sockfd, buf, len, flags, src_addr, addrlen)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(sockfd, EVENT_READABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(RECVFROM_TIMEOUT);
        del_fd_event(sockfd, EVENT_READABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #2
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t writev(int fd, const struct iovec *iov, int iovcnt)
{
    int ret;
    ssize_t n;

    while ((n = g_sys_writev(fd, iov, iovcnt)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(fd, EVENT_WRITABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(WRITEV_TIMEOUT);
        del_fd_event(fd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #3
0
파일: sys_hook.c 프로젝트: JustXxx/shark
ssize_t write(int fd, const void *buf, size_t count)
{
    ssize_t n;

    while ((n = g_sys_write(fd, buf, count)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        if (add_fd_event(fd, EVENT_WRITABLE, event_rw_callback, current_coro()))
            return -2;

        schedule_timeout(WRITE_TIMEOUT);
        del_fd_event(fd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #4
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t read(int fd, void *buf, size_t count)
{
    int ret;
    ssize_t n;

    while ((n = g_sys_read(fd, buf, count)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(fd, EVENT_READABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(READ_TIMEOUT);
        del_fd_event(fd, EVENT_READABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #5
0
static void do_accept( struct event_info *ei, void *d )
{
	struct listener *listener = (struct listener *)d;
	int fd, addrlen;
	struct sockaddr_un addr;
	struct ctl_sock *cs;

	addrlen = sizeof( addr );
	if( ( fd = accept( listener->fd, (struct sockaddr *)&addr, &addrlen ) ) < 0 )
	{
		spook_log( SL_WARN, "error accepting control connection: %s",
				strerror( errno ) );
		return;
	}
	spook_log( SL_DEBUG, "accepted control connection" );

	cs = (struct ctl_sock *)malloc( sizeof( struct ctl_sock ) );
	if( ! cs )
	{
		spook_log( SL_ERR, "out of memory on malloc ctl_sock" );
		close( fd );
		return;
	}
	cs->fd = fd;
	cs->read_event = add_fd_event( fd, 0, 0, do_read, cs );
}
예제 #6
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
{
    int ret;
    ssize_t n;

    while ((n = g_sys_sendmsg(sockfd, msg, flags)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(sockfd, EVENT_WRITABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(SENDMSG_TIMEOUT);
        del_fd_event(sockfd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #7
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t sendfile_timeout(int out_fd, int in_fd, off_t *offset, size_t count, int timeout)
{
    int ret;
    ssize_t n;

    while ((n = sendfile(out_fd, in_fd, offset, count)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(out_fd, EVENT_WRITABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(timeout * 1000);
        del_fd_event(out_fd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #8
0
파일: sys_hook.c 프로젝트: JustXxx/shark
/*
    in_fd一般就是文件fd, out_fd一定要是远端连接fd
*/
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
{
    ssize_t n;

    while ((n = g_sys_sendfile(out_fd, in_fd, offset, count)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        if (add_fd_event(out_fd, EVENT_WRITABLE, event_rw_callback, current_coro()))
            return -2;

        schedule_timeout(SENDFILE_TIMEOUT);
        del_fd_event(out_fd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #9
0
파일: sys_hook.c 프로젝트: JustXxx/shark
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
    ssize_t n;

    while ((n = g_sys_send(sockfd, buf, len, flags)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        if (add_fd_event(sockfd, EVENT_WRITABLE, event_rw_callback, current_coro()))
            return -2;

        schedule_timeout(SEND_TIMEOUT);
        del_fd_event(sockfd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #10
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                              const struct sockaddr *dest_addr, socklen_t addrlen)
{
    int ret;
    ssize_t n;

    while ((n = g_sys_sendto(sockfd, buf, len, flags, dest_addr, addrlen)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(sockfd, EVENT_WRITABLE, event_rw_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(SENDTO_TIMEOUT);
        del_fd_event(sockfd, EVENT_WRITABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #11
0
파일: sys_hook.c 프로젝트: JustXxx/shark
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
    ssize_t n;

    while ((n = g_sys_recvmsg(sockfd, msg, flags)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        if (add_fd_event(sockfd, EVENT_READABLE, event_rw_callback, current_coro()))
            return -2;

        schedule_timeout(RECVMSG_TIMEOUT);
        del_fd_event(sockfd, EVENT_READABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    return n;
}
예제 #12
0
static void
can_read (void *s, int length)
{
	struct tcp_map *map = (struct tcp_map *) s;

	if (!map->e_fd_write)
		map->e_fd_write = add_fd_event (map->fd, 1, handle_fd_can_write, map);
}
예제 #13
0
static void
output_space (void *s, int space)
{
	struct tcp_map *map = (struct tcp_map *) s;

	if (space > 0 && !map->e_fd_read)
		map->e_fd_read = add_fd_event (map->fd, 0, handle_fd_can_read, map);
}
예제 #14
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
    int ret;
    int connfd = 0;

    while ((connfd = g_sys_accept(sockfd, addr, addrlen)) < 0)
    {
        if (EINTR == errno)
            continue;

        if (!fd_not_ready())
            return -1;

        ret = add_fd_event(sockfd, EVENT_READABLE, event_conn_callback, current_coro());
        if (ret)
            return -2;

        schedule_timeout(ACCEPT_TIMEOUT);
        del_fd_event(sockfd, EVENT_READABLE);
        if (is_wakeup_by_timeout())
        {
            errno = ETIME;
            return -3;
        }
    }

    ret = set_nonblock(connfd);
    if (ret)
    {
        close(connfd);
        return -4;
    }

    ret = enable_tcp_no_delay(connfd);
    if (ret)
    {
        close(connfd);
        return -5;
    }

    ret = set_keep_alive(connfd, KEEP_ALIVE);
    if (ret)
    {
        close(connfd);
        return -6;
    }

    return connfd;
}
예제 #15
0
static void
incoming (struct tcb *t, void **d, FILE * fp)
{
	struct tcp_map *map;
	struct sockaddr_in addr;

	map = ALLOC (sizeof (struct tcp_map));
	fprintf (stderr, "number of TCP maps: %d\n", ++num_tcp_maps);
	map->next = tlist;
	map->prev = NULL;
	if (map->next)
		map->next->prev = map;
	tlist = map;
	map->fp = fp;
	map->tcb = t;
	map->e_fd_read = map->e_fd_write = NULL;
	*d = map;

	addr.sin_family = AF_INET;
	memcpy (&addr.sin_addr.s_addr, tcp_get_laddr (t) + 12, 4);
	addr.sin_port = htons (tcp_get_lport (t));

	map->fd = socket (PF_INET, SOCK_STREAM, 0);
	if (map->fd < 0) {
		perror ("socket");
		tcp_close (t, 0);
		kill_map (map);
		return;
	}
	fcntl (map->fd, F_SETFL, O_NONBLOCK);
	if (connect (map->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
		if (errno == EINPROGRESS) {
			map->e_fd_write = add_fd_event (map->fd, 1, handle_fd_did_connect, map);
		}
		else {
			perror ("connect");
			tcp_close (t, 0);
			kill_map (map);
		}
	}
	else
		tcp_accept (t);
}
예제 #16
0
파일: sys_hook.c 프로젝트: gaoyingie/shark
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    int ret;
    int flags;
    socklen_t len;

    set_nonblock(sockfd);

    /*
        connect < 0 && errno == EINPROGRESS才需要跟踪fd是否可写
        否则其他情形都是错误的, 直接返回
    */
    ret = g_sys_connect(sockfd, addr, addrlen);
    if (0 == ret)   //succ
        return 0;

    if (ret < 0 && errno != EINPROGRESS)
        return -1;

    ret = add_fd_event(sockfd, EVENT_WRITABLE, event_conn_callback, current_coro());
    if (ret)
        return -2;

    schedule_timeout(CONN_TIMEOUT);
    del_fd_event(sockfd, EVENT_WRITABLE);
    if (is_wakeup_by_timeout())
    {
        errno = ETIMEDOUT;
        return -3;
    }

    ret = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &flags, &len);
    if (ret == -1 || flags || !len)
    {
        if (flags)
            errno = flags;

        return -4;
    }

    return 0;
}
예제 #17
0
int control_listen(void)
{
	struct sockaddr_un addr;
	struct listener *listener;
	int fd;

	addr.sun_family = AF_UNIX;
	strcpy( addr.sun_path, "spook.sock" );

	unlink( addr.sun_path );
	if( ( fd = socket( PF_UNIX, SOCK_STREAM, 0 ) ) < 0 )
	{
		spook_log( SL_ERR, "error creating control socket: %s",
				strerror( errno ) );
		return -1;
	}
	if( bind( fd, (struct sockaddr *)&addr, sizeof( addr ) ) < 0 )
	{
		spook_log( SL_ERR, "unable to bind control socket: %s",
				strerror( errno ) );
		close( fd );
		return -1;
	}
	if( listen( fd, 5 ) < 0 )
	{
		spook_log( SL_ERR,
			"error attempting to listen on control socket: %s",
			strerror( errno ) );
		close( fd );
		return -1;
	}

	listener = (struct listener *)malloc( sizeof( struct listener ) );
	listener->fd = fd;

	add_fd_event( fd, 0, 0, do_accept, listener );

	spook_log( SL_INFO, "listening on control socket %s", addr.sun_path );

	return 0;
}
예제 #18
0
/* called directly from iface driver registry */
struct iface *
tap_new_if (char *dev, void (*handle_pkt) (struct iface * iface, struct pbuf * pkt))
{
	struct iface_tap *iface;

	iface = ALLOC (sizeof (struct iface_tap));
	memset (iface, 0, sizeof (struct iface_tap));

	iface->fd = get_tun (iface->devname, dev, 1);
	fcntl (iface->fd, F_SETFL, O_NONBLOCK);

	ether_setup ((struct iface_ether *) iface);
	iface->ife.pkt_handler = handle_pkt;
	iface->ife.send_frame = tap_send_frame;
	iface->ife.head_size += 4;
	memcpy (iface->ife.hwaddr, default_mac, 6);
	iface->ife.iface.mtu = 1280;

	add_fd_event (iface->fd, 0, tap_read_callback, iface);

	return (struct iface *) iface;
}
예제 #19
0
/* called directly from iface driver registry */
struct iface *
tun_new_if (char *dev, void (*handle_pkt) (struct iface * iface, struct pbuf * pkt))
{
	struct iface_tun *iface;

#ifndef HAVE_LINUX_IF_TUN_H
	fprintf (stderr, "This version of the tuntap driver doesn't support IPv6 in tun mode.\nPlease use the tap interface.\n");
	exit (1);
#endif

	iface = ALLOC (sizeof (struct iface_tun));
	iface->fd = get_tun (iface->devname, dev, 0);
	fcntl (iface->fd, F_SETFL, O_NONBLOCK);
	iface->pkt_handler = handle_pkt;
	iface->iface.mtu = 1280;
	iface->iface.hwaddr_len = 0;
	iface->iface.get_buffer = tun_get_buf;
	iface->iface.send_unicast = tun_send;
	iface->iface.send_multicast = tun_send;
	add_fd_event (iface->fd, 0, tun_read_callback, iface);

	return (struct iface *) iface;
}