Exemplo n.º 1
0
static void
send_msg_udp(struct silly_socket *ss, struct socket *s)
{
        struct wlist *w;
        w = s->wlhead.next;
        assert(w);
        while (w) {
                ssize_t sz;
                sz = sendudp(s->fd, w->buff + w->offset, w->size, &w->udpaddress);
                if (sz == -2)   //EAGAIN, so block it
                        break;
                assert(sz == -1 || sz == w->size);
                //send fail && send ok will clear
                s->wlhead.next = w->next;
                silly_free(w->buff);
                silly_free(w);
                w = s->wlhead.next;
                if (w == NULL) {//send all
                        s->wltail = &s->wlhead;
                        sp_write_enable(ss->spfd, s->fd, s, 0);
                        if (s->type == STYPE_HALFCLOSE)
                                delsocket(ss, s);
                }
        }
        return ;
}
Exemplo n.º 2
0
static int
tryudpsend(struct silly_socket *ss, struct cmdpacket *cmd)
{
        struct socket *s = checksocket(ss, cmd->u.udpsend.sid);
        uint8_t *data = cmd->u.udpsend.data;
        size_t sz = cmd->u.udpsend.size;
        const struct sockaddr *addr = &cmd->u.udpsend.to;
        if (s == NULL) {
                silly_free(data);
                return 0;
        }
        assert(s->protocol == PROTOCOL_UDP);
        if (s->type == STYPE_SOCKET) //udp client need no address
                addr = NULL;
        if (wlist_empty(s)) {//try send
                ssize_t n = sendudp(s->fd, data, sz, addr);
                if (n == -1 || n >= 0) {        //occurs error or send ok
                        silly_free(data);
                        return 0;
                }
                assert(n == -2);        //EAGAIN 
                wlist_append(s, data, 0, sz, addr);
        } else {
                wlist_append(s, data, 0, sz, addr);
        }
        return 0;
}
Exemplo n.º 3
0
static void
send_msg_tcp(struct silly_socket *ss, struct socket *s)
{
        struct wlist *w;
        w = s->wlhead.next;
        assert(w);
        while (w) {
                ssize_t sz;
                sz = sendn(s->fd, w->buff + w->offset, w->size);
                if (sz < 0) {
                        report_close(ss, s, errno);
                        delsocket(ss, s);
                        return ;
                }
                if (sz < w->size) {//send some
                        w->size -= sz;
                        w->offset += sz;
                        return ;
                }
                assert(sz == w->size);
                s->wlhead.next = w->next;
                silly_free(w->buff);
                silly_free(w);
                w = s->wlhead.next;
                if (w == NULL) {//send ok
                        s->wltail = &s->wlhead;
                        sp_write_enable(ss->spfd, s->fd, s, 0);
                        if (s->type == STYPE_HALFCLOSE)
                                delsocket(ss, s);
                }
        }
        return ;
}
Exemplo n.º 4
0
static int
trysend(struct silly_socket *ss, struct cmdpacket *cmd)
{
        struct socket *s = checksocket(ss, cmd->u.send.sid);
        uint8_t *data = cmd->u.send.data;
        size_t sz = cmd->u.send.size;
        if (s == NULL) {
                silly_free(data);
                return 0;
        }
        if (wlist_empty(s)) {//try send
                ssize_t n = sendn(s->fd, data, sz);
                if (n < 0) {
                        silly_free(data);
                        report_close(ss, s, errno);
                        delsocket(ss, s);
                        return -1;
                } else if (n < sz) {
                        wlist_append(s, data, n, sz, NULL);
                        sp_write_enable(ss->spfd, s->fd, s, 1);
                } else {
                        assert(n == sz);
                        silly_free(data);
                }
        } else {
                wlist_append(s, data, 0, sz, NULL);
        }
        return 0;
}
Exemplo n.º 5
0
static int
forward_msg_tcp(struct silly_socket *ss, struct socket *s)
{
        ssize_t sz;
        ssize_t presize = s->presize;
        uint8_t *buff = (uint8_t *)silly_malloc(presize);
        sz = readn(s->fd, buff, presize);
        //half close socket need no data
        if (sz > 0 && s->type != STYPE_HALFCLOSE) {
                report_data(ss, s, SILLY_SDATA, buff, sz);
                //to predict the pakcet size
                if (sz == presize) {
                        s->presize *= 2;
                } else if (presize > MIN_READBUFF_LEN) {
                        //s->presize at leatest is 2 * MIN_READBUFF_LEN
                        int half = presize / 2;
                        if (sz < half)
                                s->presize = half;
                }
        } else {
                silly_free(buff);
                if (sz < 0) {
                        report_close(ss, s, errno);
                        delsocket(ss, s);
                        return -1;
                }
                return 0;
        }
        return sz;
}
Exemplo n.º 6
0
int
silly_socket_udpsend(int sid, uint8_t *buff, size_t sz, const char *addr, size_t addrlen)
{
        struct cmdpacket cmd;
        struct socket *s = checksocket(SSOCKET, sid);
        if (s == NULL) {
                silly_free(buff);
                return -1;
        }
        assert(s->protocol = PROTOCOL_UDP);
        assert(s->type == STYPE_UDPBIND || s->type == STYPE_SOCKET);
        if (s->type == STYPE_UDPBIND && addr == NULL) {
                fprintf(stderr, "[socket] udpsend udpbind socket must specify dest addr\n");
                return -1;
        }
        cmd.type = 'U';
        cmd.u.udpsend.sid = sid;
        cmd.u.udpsend.data= buff;
        cmd.u.udpsend.size = sz;
        if (s->type == STYPE_UDPBIND) {//udp bind socket need sendto address
                assert(addrlen == sizeof(cmd.u.udpsend.to));
                memcpy(&cmd.u.udpsend.to, addr, sizeof(cmd.u.udpsend.to));
        }
        pipe_blockwrite(SSOCKET->ctrlsendfd, &cmd);
        return 0;
}
Exemplo n.º 7
0
void 
silly_worker_exit()
{
        lua_close(W->L);
        silly_queue_free(W->queue);
        silly_free(W);
}
Exemplo n.º 8
0
static void
wlist_free(struct socket *s)
{
        struct wlist *w;
        struct wlist *t;
        w = s->wlhead.next;
        while (w) {
                t = w;
                w = w->next;
                assert(t->buff);
                silly_free(t->buff);
                silly_free(t);
        }
        s->wlhead.next = NULL;
        s->wltail = &s->wlhead;
        return ;
}
Exemplo n.º 9
0
static int
_ldrop(lua_State *L)
{
        struct silly_message *m = (struct silly_message *)lua_touserdata(L, 1);
        if (m->type == SILLY_SOCKET_DATA) {
                struct silly_message_socket *sm = (struct silly_message_socket *)(m + 1);
                assert(sm->data);
                silly_free(sm->data);
        }
        return 0;
}
Exemplo n.º 10
0
int
silly_socket_send(int sid, uint8_t *buff,  size_t sz)
{
        struct cmdpacket cmd;
        struct socket *s = checksocket(SSOCKET, sid);
        if (s == NULL) {
                silly_free(buff);
                return -1;
        }
        if (sz == 0) {
                silly_free(buff);
                return -1;
        }
        cmd.type = 'S';
        cmd.u.send.sid = sid;
        cmd.u.send.data = buff;
        cmd.u.send.size = sz;
        pipe_blockwrite(SSOCKET->ctrlsendfd, &cmd);
        return 0;
}
Exemplo n.º 11
0
static void *
lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
{
        (void) ud;
        (void) osize;
        if (nsize == 0) {
                silly_free(ptr);
                return NULL;
        } else {
                return silly_realloc(ptr, nsize);
        }
}
Exemplo n.º 12
0
void silly_socket_exit()
{
        int i;
        assert(SSOCKET);
        sp_free(SSOCKET->spfd);
        close(SSOCKET->ctrlsendfd);
        close(SSOCKET->ctrlrecvfd);

        struct socket *s = &SSOCKET->socketpool[0];
        for (i = 0; i < MAX_SOCKET_COUNT; i++) {
                int isnormal = 0;
                enum stype type = s->type;
                isnormal += type == STYPE_SOCKET ? 1 : 0;
                isnormal += type == STYPE_LISTEN ? 1 : 0;
                isnormal += type == STYPE_HALFCLOSE ? 1 : 0;
                if (isnormal > 0)
                        close(s->fd);
        }
        silly_free(SSOCKET->eventbuff);
        silly_free(SSOCKET->socketpool);
        silly_free(SSOCKET);
        return ;
}
Exemplo n.º 13
0
void
silly_queue_free(struct silly_queue *q)
{
	struct silly_message *next, *tmp;
	lock(q);
	next = q->head.next;
	while (next) {
		tmp = next;
		next = next->next;
		silly_message_free(tmp);
	}
	unlock(q);
	silly_free(q);
	return ;
}
Exemplo n.º 14
0
int
silly_socket_init()
{
        int err;
        sp_t spfd = SP_INVALID;
        int fd[2] = {-1, -1};
        struct socket *s = NULL;
        struct silly_socket *ss = silly_malloc(sizeof(*ss));
        memset(ss, 0, sizeof(*ss));
        socketpool_init(ss);
        spfd = sp_create(EVENT_SIZE);
        if (spfd == SP_INVALID)
                goto end;
        s = allocsocket(ss, STYPE_CTRL, PROTOCOL_PIPE);
        assert(s);
        err = pipe(fd); //use the pipe and not the socketpair because the pipe will be automatic when the data size small than BUFF_SIZE
        if (err < 0)
                goto end;
        err = sp_add(spfd, fd[0], s);
        if (err < 0)
                goto end;
        ss->spfd = spfd;
        ss->ctrlsendfd = fd[1];
        ss->ctrlrecvfd = fd[0];
        ss->eventindex = 0;
        ss->eventcount = 0;
        resize_eventbuff(ss, EVENT_SIZE);
        FD_ZERO(&ss->ctrlfdset);
        SSOCKET = ss;
        return 0;
end:
        if (s)
                freesocket(ss, s);
        if (spfd != SP_INVALID)
                sp_free(spfd);
        if (fd[0] >= 0)
                close(fd[0]);
        if (fd[1] >= 0)
                close(fd[0]);
        if (ss)
                silly_free(ss);

        return -errno;
}
Exemplo n.º 15
0
static inline void
freenode(struct node *n)
{
	silly_free(n);
	return ;
}