Example #1
0
void
handle_accept(struct net_service* service, int ret, int err, struct accept_session*	asession)
{
    struct net_session*	session;

    unsigned int			session_index;

//	asession = (struct accept_session*)ov_data;

    if( !asession || asession->id == 0)
    {
        release_accept_session(asession);
        return;
    }
    session_index = ffid_index(service->socket_ids, asession->id);
    net_lock(&service->session_lock[session_index]);
    session = service->sessions[session_index];

    if (!ret && err)
    {
        net_close_fd(asession->accept_socket);
        if (!session || !session->lsession || session->id != asession->id)
        {
            net_unlock(&service->session_lock[session_index]);
            push_queue_with_lock(service, asession->id, Eve_Post_Listen_Error);
            release_accept_session(asession);
            return;
        }
    }
    else
    {
        if (!session || !session->lsession || session->id != asession->id)
        {
            net_unlock(&service->session_lock[session_index]);
            push_queue_with_lock(service, asession->id, Eve_Post_Listen_Error);
            release_accept_session(asession);
            return;
        }
        if (!push_queue(service, session, Eve_Accept))
        {
            net_close_fd(asession->accept_socket);
        }
        else if (msg_buff_write(session->lsession->socket_queue, (void*)&asession->accept_socket) != 1)
        {
            net_close_fd(asession->accept_socket);
        }
        else
        {
            setsockopt(asession->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&session->fd, sizeof(session->fd));
        }
    }

    net_unlock(&service->session_lock[session_index]);
    asession->accept_socket = 0;
    if(post_listen(service, session, asession))
    {
        release_accept_session(asession);
        push_queue_with_lock(service, session->id, Eve_Post_Listen_Error);
    }
}
Example #2
0
NET_API net_socket
net_accept(struct net_service* service, net_socket fd)
{
    struct net_session* session;
    struct net_session* accept_session;
    unsigned short index;
    NET_SOCKET s;

    if(!service || fd == 0)
    {
        return 0;
    }
    index = ffid_index(service->socket_ids, fd);
    net_lock(&service->session_lock[index]);
    session = service->sessions[index];
    if(!session || !session->lsession || session->id != fd)
    {
        net_unlock(&service->session_lock[index]);
        return 0;
    }
    if(msg_buff_read(session->lsession->socket_queue, &s, 1) != 1)
    {
        net_unlock(&service->session_lock[index]);
        return 0;
    }
    net_unlock(&service->session_lock[index]);

    accept_session = create_and_add_net_session(service, s);
    if(!accept_session)
    {
        net_close_fd(s);
        return 0;
    }
    return accept_session->id;
}
Example #3
0
NET_API net_socket
net_accept(struct net_service* service, net_socket nd)
{
	unsigned short index;
	struct net_session* session;
	struct net_session* new_session;
	int fd;
	ffid_vtype id;

	if(!service || !nd) return 0;

	index = ffid_index(service->socket_ids, nd);
	net_lock(&service->session_lock[index]);
	session = service->sessions[index];
	if(!session ||  !session->lsession || session->id != nd)
	{
		net_unlock(&service->session_lock[index]);
		return 0;
	}
	fd = accept(session->fd, 0, 0);
	if(fd < 0)
	{
		net_unlock(&service->session_lock[index]);
		
		return 0;
	}
	ctl_socket_async(fd);
	new_session = create_net_session();
	if(!new_session)
	{
		net_close_fd(fd);
		net_unlock(&service->session_lock[index]);
		return 0;
	}
	net_unlock(&service->session_lock[index]);

	new_session->fd = fd;

	id = add_net_session(service, new_session);
	if(!id)
	{
		release_net_session(new_session);
		net_close_fd(fd);
		return 0;
	}
	return id;
}
Example #4
0
NET_API void
net_socket_close(struct net_service* service, net_socket nd, char send_rest)
{
	unsigned short index;
	struct net_session* session;
	sb_tree_value v;

	if(!service)
	{
		return;
	}
	if(!nd)
	{
		return;
	}

	index = ffid_index(service->socket_ids, nd);
	net_lock(&service->session_lock[index]);
	session = service->sessions[index];
	if(!session || session->id != nd)
	{
		net_unlock(&service->session_lock[index]);
		return;
	}
	// epoll_ctl(service->net_service_fd, EPOLL_CTL_DEL, session->fd, 0);
	clean_epoll_op(service, session);
	if(send_rest)
	{
		post_write(service, session);
	}
	
	service->sessions[index] = 0;
	// release read session
	release_read_session(session->rsession);
	session->rsession = 0;

	if(session->wsession && session->wsession->op == OP_NET_WRITE)
	{
		session->wsession->send_rest = send_rest;
		shutdown(session->fd, 0);
		release_listen_session(session->lsession);
		session->lsession = 0;
		// join to close_root sb_tree
		net_lock(&service->close_lock);
		v.ptr = session;
		sb_tree_insert(&service->close_root , nd, v);
		net_unlock(&service->close_lock);
	}
	else
	{
		net_close_fd(session->fd);
		release_net_session(session);
	}
	net_unlock(&service->session_lock[index]);

	net_lock(&service->id_lock);
	ffid_del_id(service->socket_ids, nd);
	net_unlock(&service->id_lock);
}
Example #5
0
void daemon_terminate( int sig, const char *name )
{
	alarm(0);
	printf("daemon_terminate: %s\n", name);

	net_close_fd();
	exit(0);
}
Example #6
0
void
release_rest_session(struct net_service* service, struct net_session* session)
{
	net_lock(&service->close_lock);
	sb_tree_delete(&service->close_root, session->id);
	net_unlock(&service->close_lock);

	clean_epoll_op(service, session);

	net_close_fd(session->fd);
	release_net_session(session);
}
Example #7
0
void
release_accept_session(struct accept_session* asession)
{
    if(!asession)
    {
        return;
    }
    if(asession->accept_socket)
    {
        net_close_fd(asession->accept_socket);
    }
    free(asession);
}
Example #8
0
NET_API void
net_socket_close(struct net_service* service, net_socket nd, char send_rest)
{
    unsigned short index;
    struct net_session* session;

    if(!service)
    {
        return;
    }
    if(!nd)
    {
        return;
    }

    index = ffid_index(service->socket_ids, nd);
    net_lock(&service->session_lock[index]);
    session = service->sessions[index];
    if(!session || session->id != nd)
    {
        net_unlock(&service->session_lock[index]);
        return;
    }
    if(send_rest)
    {
        post_write(service, session);
    }

    service->sessions[index] = 0;

    if(session->wsession && session->wsession->op == OP_NET_WRITE)
    {
        shutdown(session->fd, 0);
        session->wsession->fd = session->fd;
        session->wsession->send_rest = send_rest;
    }
    else
    {
        shutdown(session->fd, SD_BOTH);
        net_close_fd(session->fd);
    }
    release_net_session(session);
    net_unlock(&service->session_lock[index]);

    net_lock(&service->id_lock);
    ffid_del_id(service->socket_ids, nd);
    net_unlock(&service->id_lock);
}
Example #9
0
int
post_listen(struct net_service* service, struct net_session* session, struct accept_session* asession)
{
    NET_SOCKET accept_socket;
    int err;

    accept_socket = create_socket();
    if(NET_INVALID_SOCKET == accept_socket)
    {
        return -1;
    }

    CreateIoCompletionPort((HANDLE)accept_socket, service->net_service_fd, (ULONG_PTR)accept_socket, sizeof(NET_SOCKET));
    memset(asession, 0, sizeof(struct accept_session));
    asession->id = session->id;
    asession->accept_socket = accept_socket;
    asession->op = OP_NET_ACCEPT;

    if(!AcceptEx(
                session->fd,
                accept_socket,
                asession->data_buf,
                0,
                sizeof(struct sockaddr_in) + 32,
                sizeof(struct sockaddr_in) + 32,
                &asession->recv_bytes,
                &asession->overlapped
            ))
    {
        err = net_get_error();
        if(ERROR_IO_PENDING != err)
        {
            net_close_fd(accept_socket);
            return err;
        }
    }
    return NO_ERROR;
}
Example #10
0
void
release_listen_session(struct listen_session* lsession)
{
    NET_SOCKET s[32];
    int cnt, i;

    if(!lsession)
    {
        return;
    }
    if(lsession->socket_queue)
    {
        while((cnt = msg_buff_read(lsession->socket_queue, s, sizeof(s)/sizeof(s[0]))))
        {
            for(i = 0; i < cnt; ++i)
            {
                net_close_fd(s[i]);
            }
        }
        msg_buff_release(lsession->socket_queue);
    }
    free(lsession);
}
Example #11
0
NET_API net_socket
net_connect(struct net_service* service, const char* ip, unsigned short port)
{
	int connect_socket;
	struct sockaddr_in connect_addr;
	struct epoll_event ev;
	struct net_session* session;
	int ret;
	ffid_vtype id;

	connect_socket = create_socket();
	if(connect_socket < 0)
	{
		return 0;
	}
	ctl_socket_async(connect_socket);


	session = create_net_session();
	if(!session)
	{
		net_close_fd(connect_socket);
		return 0;
	}
	session->fd = connect_socket;
	session->connect_flag = 1;

	id = add_net_session(service, session);
	if(!id)
	{
		release_net_session(session);
		net_close_fd(connect_socket);
		return 0;
	}

	memset(&connect_addr, 0, sizeof(connect_addr));
	connect_addr.sin_family = AF_INET;
	connect_addr.sin_addr.s_addr = inet_addr(ip);
	connect_addr.sin_port = htons(port);

	ret = connect(connect_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr));
	if(ret < 0)
	{
		ret = net_get_error();
		if(ret != EINPROGRESS)
		{
			net_socket_close_print_error();
			net_socket_close(service, id, 0);
			return 0;
		}
	}

	memset(&ev, 0, sizeof(ev));
	ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ev.data.u64 = session->id;
	if((ret = epoll_ctl(service->net_service_fd, EPOLL_CTL_ADD, connect_socket, &ev)))
	{
		ret = net_get_error();
		net_socket_close_print_error();
		net_socket_close(service, id, 0);
		return 0;
	}

	return id;
}
Example #12
0
NET_API net_socket
net_listen(struct net_service* service, unsigned short port, unsigned short listen_cnt)
{
	int listen_socket;
	int opt;
	struct sockaddr_in listen_addr;
	struct epoll_event ev;
	struct net_session* session;
	int ret;
	ffid_vtype id;

	listen_socket = create_socket();
	if(listen_socket < 0)
	{
		// printf("listen error step 0 %d\n", ret);
		// perror("info:");
		return 0;
	}
	opt = 1;
	// listen socket reuse
	setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
	ctl_socket_async(listen_socket);

	listen_addr.sin_family = AF_INET;
	listen_addr.sin_port = htons(port);
	listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if((ret = bind(listen_socket, (struct sockaddr*)&listen_addr, sizeof(listen_addr))))
	{
		ret = net_get_error();
		// printf("listen error step 1 %d\n", ret);
		// perror("info:");
		net_close_fd(listen_socket);

		return 0;
	}

	if((ret = listen(listen_socket, listen_cnt)))
	{
		ret = net_get_error();
		// printf("listen error step 2 %d\n", ret);
		// perror("info:");
		net_close_fd(listen_socket);
		return 0;
	}

	session = create_net_session();
	if(!session)
	{
		// printf("listen error step 3\n");
		net_close_fd(listen_socket);
		return 0;
	}
	session->fd = listen_socket;
	session->lsession = create_listen_session(service, port, listen_cnt);
	if(!session->lsession)
	{
		// printf("listen error step 4 \n");
		release_net_session(session);
		net_close_fd(listen_socket);
		return 0;
	}

	id = add_net_session(service, session);
	if(!id)
	{
		// printf("listen error step 5 \n");
		release_net_session(session);
		net_close_fd(listen_socket);
		return 0;
	}

	memset(&ev, 0, sizeof(ev));
	ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
	ev.data.u64 = session->id;
	if((ret = epoll_ctl(service->net_service_fd, EPOLL_CTL_ADD, listen_socket, &ev)))
	{
		ret = net_get_error();
		// printf("listen error step 6 %d\n", ret);
		// perror("info:");
		net_socket_close_print_error();
		net_socket_close(service, id, 0);
		return 0;
	}
	return id;
}
Example #13
0
NET_API net_socket
net_connect(struct net_service* service, const char* ip, unsigned short port)
{
    NET_SOCKET s;
    struct sockaddr_in connect_addr;
    struct net_session* session;
    struct connect_session* csession;
    ffid_vtype id;
    FUN_CONNECTEX connectExFun;
    int err;

    s = create_socket();
    if(NET_INVALID_SOCKET == s)
    {
        return 0;
    }
    memset(&connect_addr, 0, sizeof(connect_addr));
    connect_addr.sin_family = AF_INET;
    connect_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    connect_addr.sin_port = 0;

    if(bind(s, (struct sockaddr*)&connect_addr, sizeof(connect_addr)))
    {
        net_close_fd(s);
        return 0;
    }

    connectExFun = 0;
    connectExFun = get_connect_ex_fun(s);
    if(!connectExFun)
    {
        net_close_fd(s);
        return 0;
    }

    CreateIoCompletionPort((HANDLE)s, service->net_service_fd, (ULONG_PTR)s, sizeof(NET_SOCKET));

    csession = (struct connect_session*)malloc(sizeof(struct connect_session));
    if(!csession)
    {
        net_close_fd(s);
        return 0;
    }
    memset(csession, 0, sizeof(struct connect_session));
    csession->s = s;

    session = create_net_session();
    if(!session)
    {
        net_close_fd(s);
        release_connect_session(csession);
        return 0;
    }

    id = add_net_session(service, session);
    if(!id)
    {
        net_close_fd(s);
        release_net_session(session);
        release_connect_session(csession);
        return 0;
    }
    memset(&connect_addr, 0, sizeof(connect_addr));
    connect_addr.sin_family = AF_INET;
    connect_addr.sin_addr.S_un.S_addr = inet_addr(ip);
    connect_addr.sin_port = htons(port);


    csession->id = id;
    csession->op = OP_NET_CONNECT;

    session->connect_flag = 1;
    session->fd = s;
    session->data = 0;


    if(!connectExFun(s, (struct sockaddr*)&connect_addr, (int)sizeof(connect_addr),
                     0, 0, (LPDWORD)&csession->send_bytes, (LPOVERLAPPED)&csession->overlapped))
    {
        err = net_get_error();
        if(err != ERROR_IO_PENDING)
        {
            release_connect_session(csession);
            net_socket_close(service, id, 0);
            return 0;
        }
    }
    return id;
}
Example #14
0
NET_API net_socket
net_listen(struct net_service* service, unsigned short port, unsigned short listen_cnt)
{
    ffid_vtype id;
    NET_SOCKET listen_socket;
    struct net_session* session;
    struct sockaddr_in listen_addr;
    struct accept_session* asession;
    int i, ret;

    listen_socket = create_socket();
    if(NET_INVALID_SOCKET == listen_socket)
    {
        return 0;
    }
    CreateIoCompletionPort((HANDLE)listen_socket, service->net_service_fd, (ULONG_PTR)listen_socket, sizeof(NET_SOCKET));
    listen_addr.sin_family = AF_INET;
    listen_addr.sin_port = htons(port);
    listen_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    if((ret = bind(listen_socket, (struct sockaddr*)&listen_addr, sizeof(listen_addr))))
    {
        ret = net_get_error();
        net_close_fd(listen_socket);
        return 0;
    }
    if(listen(listen_socket, listen_cnt))
    {
        net_close_fd(listen_socket);
        return 0;
    }
    session = create_net_session();
    if(!session)
    {
        net_close_fd(listen_socket);
        return 0;
    }
    session->fd = listen_socket;
    session->lsession = create_listen_session(service, port, listen_cnt);
    if(!session->lsession)
    {
        release_net_session(session);
        net_close_fd(listen_socket);
        return 0;
    }

    id = add_net_session(service, session);
    if(!id)
    {
        release_net_session(session);
        net_close_fd(listen_socket);
        return 0;
    }

    for(i = 0; i < listen_cnt; ++i)
    {
        asession = create_accept_session();
        if(asession)
        {
            if(!post_listen(service, session, asession))
            {
                asession->index = i;
                continue;
            }
            release_accept_session(asession);
        }
        net_socket_close(service, id, 0);
        return 0;
    }
    return id;
}
Example #15
0
static int _handleconn (int delay_time, int max_cost_time, int error)
{
	if (error) {
		if (error == 1) {
			daemon_printf( "%d server temporarily unavailable\n", CODE_TEMPORARILY_UNAVAILABLE );
			printf("daemon busy: temporarily unavailable\n");
		} else {
			printf("daemon too busy: drop connection\n");
		}
		net_close_fd();
		return 0;
	}

	daemon_banner();

	std::string buf;
	std::vector<std::string> *args;
	alarm(delay_time);
	while (true) {
		if (net_read_line(buf))
			break;
		alarm(max_cost_time);
		printf("%s\n", buf.c_str());
		args = args_new(buf.c_str());
		if (args->size() == 0) {
			daemon_printf( "%d no command\n", CODE_SYNTAX_ERROR );
		} else if ((*args)[0] == "client" && args->size()>=3) {
			daemon_client((*args)[1], (*args)[2]);
		} else if ((*args)[0] == "auth" && args->size()>=3) {
			daemon_auth((*args)[1], (*args)[2]);
		} else if ((*args)[0] == "lookup" && args->size()>=2) {
			if (args->size() >=3) {
				int wordcount = atoi((*args)[2].c_str());
				if (wordcount < 1) {
					wordcount = 1;
				} else if (wordcount > 100) {
					wordcount = 100;
				}
				daemon_lookup((*args)[1], wordcount);
			} else {
				daemon_lookup((*args)[1], 30);
			}
		} else if ((*args)[0] == "query" && args->size()>=2) {
			daemon_query((*args)[1]);
		} else if ((*args)[0] == "selectquery" && args->size()>=2) {
			daemon_selectquery((*args)[1]);
		} else if ((*args)[0] == "smartquery" && args->size()>=3) {
			daemon_smartquery((*args)[1], (*args)[2]);
		} else if ((*args)[0] == "define" && args->size()>=2) {
			daemon_define((*args)[1]);
		} else if ((*args)[0] == "previous" && args->size()>=2) {
			if (args->size() >=3) {
				int wordcount = atoi((*args)[2].c_str());
				if (wordcount < 1) {
					wordcount = 1;
				} else if (wordcount > 50) {
					wordcount = 50;
				}
				daemon_previous((*args)[1], wordcount);
			} else {
				daemon_previous((*args)[1], 15);
			}
		} else if ((*args)[0] == "next" && args->size()>=2) {
			if (args->size() >=3) {
				int wordcount = atoi((*args)[2].c_str());
				if (wordcount < 1) {
					wordcount = 1;
				} else if (wordcount > 100) {
					wordcount = 100;
				}
				daemon_next((*args)[1], wordcount);
			} else {
				daemon_next((*args)[1], 30);
			}
		} else if ((*args)[0] == "quit" && args->size()>=1) {
			daemon_quit();
		} else if ((*args)[0] == "register" && args->size()>=4) {
			daemon_register((*args)[1], (*args)[2], (*args)[3]);
		} else if ((*args)[0] == "change_password" && args->size()>=4) {
			daemon_change_password((*args)[1], (*args)[2], (*args)[3]);
		} else if ((*args)[0] == "setdictmask" && args->size()>=2) {
			daemon_setdictmask((*args)[1]);
		} else if ((*args)[0] == "getdictmask" && args->size()>=1) {
			daemon_getdictmask();
		} else if ((*args)[0] == "setcollatefunc" && args->size()>=2) {
			daemon_setcollatefunc((*args)[1]);
		} else if ((*args)[0] == "getcollatefunc" && args->size()>=1) {
			daemon_getcollatefunc();
		} else if ((*args)[0] == "setlanguage" && args->size()>=2) {
			daemon_setlanguage((*args)[1]);
		} else if ((*args)[0] == "getlanguage" && args->size()>=1) {
			daemon_getlanguage();
		} else if ((*args)[0] == "setemail" && args->size()>=2) {
			daemon_setemail((*args)[1]);
		} else if ((*args)[0] == "getemail" && args->size()>=1) {
			daemon_getemail();
		} else if ((*args)[0] == "getuserlevel" && args->size()>=1) {
			daemon_getuserlevel();
		} else if ((*args)[0] == "maxdictcount" && args->size()>=1) {
			daemon_maxdictcount();
		} else if ((*args)[0] == "dirinfo" && args->size()>=2) {
			daemon_dirinfo((*args)[1]);
		} else if ((*args)[0] == "dictinfo" && args->size()>=2) {
			daemon_dictinfo((*args)[1]);
		} else if ((*args)[0] == "userlevel" && args->size()>=4) {
			daemon_userlevel((*args)[1], (*args)[2], (*args)[3]);
		} else if ((*args)[0] == "fromto" && args->size() >= 1) {
			daemon_fromto();
		} else if ((*args)[0] == "dictslist" && args->size()>=2) {
			daemon_dictslist((*args)[1]);
		} else if ((*args)[0] == "tmpdictmask" && args->size() >= 2) {
			daemon_LookupinTmpdictmask((*args)[1]);
		} else if ((*args)[0] == "getadinfo" && args->size()>=1) {
			daemon_getadinfo();
		} else {
			daemon_printf( "%d unknown command\n", CODE_SYNTAX_ERROR );
		}
		delete args;
		alarm(delay_time);
	}
	daemon_terminate( 0, "close" );
	return 0;
}