예제 #1
0
int
socket_server_udp(struct socket_server *ss, uintptr_t opaque, const char * addr, int port) {
    int fd;
    int family;
    if (port != 0 || addr != NULL) {
        // bind
        fd = do_bind(addr, port, IPPROTO_UDP, &family);
        if (fd < 0) {
            return -1;
        }
    } else {
        family = AF_INET;
        fd = socket(family, SOCK_DGRAM, 0);
        if (fd < 0) {
            return -1;
        }
    }
    sp_nonblocking(fd);

    int id = reserve_id(ss);
    if (id < 0) {
        close(fd);
        return -1;
    }
    struct request_package request;
    request.u.udp.id = id;
    request.u.udp.fd = fd;
    request.u.udp.opaque = opaque;
    request.u.udp.family = family;

    send_request(ss, &request, 'U', sizeof(request.u.udp));
    return id;
}
예제 #2
0
// return 0 when failed
static int
report_accept(struct socket_server *ss, struct socket *s, struct socket_message *result) {
	union sockaddr_all u;
	socklen_t len = sizeof(u);
	int client_fd = accept(s->fd, &u.s, &len);
	if (client_fd < 0) {
		return 0;
	}
	int id = reserve_id(ss);
	if (id < 0) {
		close(client_fd);
		return 0;
	}
	sp_nonblocking(client_fd);
	struct socket *ns = new_fd(ss, id, client_fd, s->opaque, false);
	if (ns == NULL) {
		close(client_fd);
		return 0;
	}
	ns->type = SOCKET_TYPE_PACCEPT;
	result->opaque = s->opaque;
	result->id = s->id;
	result->ud = id;
	result->data = NULL;

	void * sin_addr = (u.s.sa_family == AF_INET) ? (void*)&u.v4.sin_addr : (void *)&u.v6.sin6_addr;
	if (inet_ntop(u.s.sa_family, sin_addr, ss->buffer, sizeof(ss->buffer))) {
		result->data = ss->buffer;
	}

	return 1;
}
예제 #3
0
int
socket_server_bind(struct socket_server *ss, uintptr_t opaque, int fd) {
	struct request_package request;
	int id = reserve_id(ss);
	request.u.bind.opaque = opaque;
	request.u.bind.id = id;
	request.u.bind.fd = fd;
	send_request(ss, &request, 'B', sizeof(request.u.bind));
	return id;
}
예제 #4
0
int socket_server::server_bind(uintptr_t opaque, int fd) 
{
    struct request_package request;
    int id = reserve_id();
    if (id < 0) {
        return -1;
    }
    request.u.bind.opaque = opaque;
    request.u.bind.id = id;
    request.u.bind.fd = fd;
    send_request(&request, 'B', sizeof(request.u.bind));
    return id;
}
예제 #5
0
int 
socket_server_listen(struct socket_server *ss, uintptr_t opaque, const char * addr, int port, int backlog) {
	int fd = do_listen(addr, port, backlog);
	if (fd < 0) {
		return -1;
	}
	struct request_package request;
	int id = reserve_id(ss);
	request.u.listen.opaque = opaque;
	request.u.listen.id = id;
	request.u.listen.fd = fd;
	send_request(ss, &request, 'L', sizeof(request.u.listen));
	return id;
}
예제 #6
0
// return 0 when failed, or -1 when file limit
// 
static int
report_accept(struct socket_server *ss, struct socket *s, struct socket_message *result) {
	union sockaddr_all u;
	socklen_t len = sizeof(u);
	// 生成被动套接字
	int client_fd = accept(s->fd, &u.s, &len);
	if (client_fd < 0) {
		if (errno == EMFILE || errno == ENFILE) {
			result->opaque = s->opaque;
			result->id = s->id;
			result->ud = 0;
			result->data = strerror(errno);
			return -1;
		} else {
			return 0;
		}
	}
	// 分配id
	int id = reserve_id(ss);
	if (id < 0) {
		close(client_fd);
		return 0;
	}
	// 设置keepalive和非阻塞
	socket_keepalive(client_fd);
	sp_nonblocking(client_fd);
	// 创建socket实例
	struct socket *ns = new_fd(ss, id, client_fd, PROTOCOL_TCP, s->opaque, false);
	if (ns == NULL) {
		close(client_fd);
		return 0;
	}
	// 设置socket类型为PACCEPT
	ns->type = SOCKET_TYPE_PACCEPT;
	result->opaque = s->opaque;
	result->id = s->id;			// 服务器套接字id
	result->ud = id;			// 被动套接字id
	result->data = NULL;		// 连接客户端ip地址:port端口

	void * sin_addr = (u.s.sa_family == AF_INET) ? (void*)&u.v4.sin_addr : (void *)&u.v6.sin6_addr;
	int sin_port = ntohs((u.s.sa_family == AF_INET) ? u.v4.sin_port : u.v6.sin6_port);
	char tmp[INET6_ADDRSTRLEN];
	if (inet_ntop(u.s.sa_family, sin_addr, tmp, sizeof(tmp))) {
		snprintf(ss->buffer, sizeof(ss->buffer), "%s:%d", tmp, sin_port);
		result->data = ss->buffer;
	}

	return 1;
}
예제 #7
0
static int
open_request(struct socket_server *ss, struct request_package *req, uintptr_t opaque, const char *addr, int port) {
	int len = strlen(addr);
	if (len + sizeof(req->u.open) > 256) {
		fprintf(stderr, "socket-server : Invalid addr %s.\n",addr);
		return 0;
	}
	int id = reserve_id(ss);
	req->u.open.opaque = opaque;
	req->u.open.id = id;
	req->u.open.port = port;
	memcpy(req->u.open.host, addr, len);
	req->u.open.host[len] = '\0';

	return len;
}
예제 #8
0
파일: net.cpp 프로젝트: setlin/jserver
// new a net socket node
// the add parametic means that let fd add to eventfd immediately or not
static struct net_socket* net_socket_new(struct net_pool* np, int fd, bool add)
{
    log_debug("net_socket_new\n");
    // judge the capacity is full or not
    if(np->count >= np->cap)
    {
        net_expand(np);
    }

    // get the unique id for fd
    int id = reserve_id(np);
    if(id < 0)
    {
        log_error("reserve id failure");
        return NULL;
    }

    struct net_socket* ns = np->ns[id % np->cap];
    // TODO: use assert?
    // assert(ns->status == SOCKET_STATUS_RESERVE);
    if(ns->status != SOCKET_STATUS_RESERVE)
    {
        log_error("get allocid failure");
        return NULL;
    }

    // add to eventfd or not
    if(add)
    {
        if(poll_add(np->eventfd, fd, ns))
        {
            log_error("add fd to eventfd failure");
            ns->status = SOCKET_STATUS_INVALID;
            return NULL;
        }
    }
    ns->fd = fd;
    np->count++;

    log_debug("[current client count] : %d\n", np->count);

    return ns;
}
예제 #9
0
int socket_server::server_listen(uintptr_t opaque, const char *addr, int port, int backlog)
{
    int fd = do_listen(addr, port, backlog);
    if (fd < 0) {
        printf("do listen failed\n");
        return -1;
    }
    printf("run listen success!\n");

    struct request_package request;
    int id = reserve_id();
    if (id < 0) {
        close(fd);
        return id;
    }
    request.u.listen.opaque = opaque;
    request.u.listen.id = id;
    request.u.listen.fd = fd;
    send_request(&request, 'L', sizeof(request.u.listen));
    return id;
}
예제 #10
0
// return 0 when failed
static int
report_accept(struct socket_server *ss, struct socket *s, struct socket_message *result) {
	union sockaddr_all u;
	socklen_t len = sizeof(u);
	int client_fd = accept(s->fd, &u.s, &len);
	if (client_fd < 0) {
		//printf("accept error : %s\n", strerror(errno));
		return 0;
	}
	int id = reserve_id(ss);
	if (id < 0) {
		close(client_fd);
		return 0;
	}
	socket_keepalive(client_fd);
	sp_nonblocking(client_fd);
	struct socket *ns = new_fd(ss, id, client_fd, s->opaque, false);
	if (ns == NULL) {
		close(client_fd);
		return 0;
	}
	ns->type = SOCKET_TYPE_PACCEPT;
	result->opaque = s->opaque;
	result->id = s->id;
	result->ud = id;
	result->data = NULL;

	void * sin_addr = (u.s.sa_family == AF_INET) ? (void*)&u.v4.sin_addr : (void *)&u.v6.sin6_addr;
	int sin_port = ntohs((u.s.sa_family == AF_INET) ? u.v4.sin_port : u.v6.sin6_port);
	char tmp[INET6_ADDRSTRLEN];
	if (inet_ntop(u.s.sa_family, sin_addr, tmp, sizeof(tmp))) {
		snprintf(ss->buffer, sizeof(ss->buffer), "%s:%d", tmp, sin_port);
		result->data = ss->buffer;
	}

	return 1;
}
예제 #11
0
int socket_server::report_accept(struct socket *s, struct socket_message *result)
{
    union sockaddr_all u;
    socklen_t len = sizeof(u);
    int client_fd = accept(s->fd, &u.s, &len);
    if (client_fd < 0) {
        return 0;
    }
    int id = reserve_id();
    if (id < 0) {
        close(client_fd);
        return 0;
    }
    keepalive(client_fd);
    nonblocking(client_fd);

    struct socket *ns = new_socket(id, client_fd, PROTOCOL_TCP, s->opaque, false);
    if (ns == nullptr) {
        close(client_fd);
        return 0;
    }
    ns->type = SOCKET_TYPE_PACCEPT;
    result->opaque = s->opaque;
    result->id = s->id;
    result->ud = id;
    result->data = nullptr;

    void * sin_addr = (u.s.sa_family == AF_INET) ? (void *)&u.v4.sin_addr : (void *)&u.v6.sin6_addr;
    int sin_port = ntohs((u.s.sa_family == AF_INET) ? u.v4.sin_port : u.v6.sin6_port);
    char tmp[INET6_ADDRSTRLEN];
    if (inet_ntop(u.s.sa_family, sin_addr, tmp, sizeof(tmp))) {
        snprintf(buffer, sizeof(buffer), "%s:%d", tmp, sin_port);
        result->data = buffer;
    }

    return 1;
}