Example #1
0
static
dbms_error_t 
i_comms(
	dbms * me,
	int token,
	int *retval,
	DBT * v1,
	DBT * v2,
	DBT * r1,
	DBT * r2
)
{
	int             err = 0;
	DBT             rr1, rr2;
	struct header   cmd;
	struct iovec    iov[3];
	struct msghdr   msg;
	size_t          s;

	if (retval)
		*retval = -1;

	rr1.data = rr2.data = NULL;

	cmd.token = token | F_CLIENT_SIDE;

	cmd.len1 = htonl((v1 == NULL) ? 0 : v1->size);
	cmd.len2 = htonl((v2 == NULL) ? 0 : v2->size);

	iov[0].iov_base = (char *) &cmd;
	iov[0].iov_len = sizeof(cmd);

	iov[1].iov_base = (v1 == NULL) ? NULL : v1->data;
	iov[1].iov_len = (v1 == NULL) ? 0 : v1->size;

	iov[2].iov_base = (v2 == NULL) ? NULL : v2->data;
	iov[2].iov_len = (v2 == NULL) ? 0 : v2->size;

#ifdef STATIC_CS_BUFF
	if (iov[0].iov_len + iov[1].iov_len + iov[2].iov_len > MAX_CS_PAYLOAD)
		return E_TOOBIG;
#endif
	msg.msg_name = NULL;
	msg.msg_namelen = 0;
	msg.msg_iov = iov;
	msg.msg_iovlen = 3;
/* temporal fix to make CYGWN compile the basic thing - need better solution */
#ifndef RDFSTORE_PLATFORM_CYGWIN
	msg.msg_control = NULL;
	msg.msg_controllen = 0;
	msg.msg_flags = 0;
#endif
	s = sendmsg(me->sockfd, &msg, 0);

	if (s == 0) {
		err = E_CLOSE;
		goto retry_com;
	} else if (s < 0) {
		mark_dbms_error(me, "sendmsg()", errno);
		err = E_ERROR;
		goto retry_com;
	} else if (s != iov[0].iov_len + iov[1].iov_len + iov[2].iov_len) {
		err = E_FULLWRITE;
		goto exit_com;
	};

	s = recv(me->sockfd, &cmd, sizeof(cmd), 0);

	if (s == 0) {
		err = E_CLOSE;
		goto retry_com;
	} else if (s < 0) {
		mark_dbms_error(me, "header-recv()", errno);
		err = E_ERROR;
		goto retry_com;
	} else if (s != sizeof(cmd)) {
		err = E_FULLREAD;
		goto exit_com;
	};

	cmd.len1 = ntohl(cmd.len1);
	cmd.len2 = ntohl(cmd.len2);

	rr2.data = rr1.data = NULL;
	if ((err = getpack(me, cmd.len1, r1 ? r1 : &rr1)) != 0)
		goto retry_com;

	if ((err = getpack(me, cmd.len2, r2 ? r2 : &rr2)) != 0)
		goto retry_com;

	if ((cmd.token & MASK_TOKEN) == TOKEN_ERROR) {
		char           *d = NULL;
		int             l = 0;
		if (r1) {
			l = r1->size;
			d = r1->data;
		} else {
			l = rr1.size;
			d = rr1.data;
		};
		errno = 0;
		if ((d) && (l > 0)) {
			d[l] = '\0';
		} else {
			d = "DBMS side errror, no cause reported";
		};
		err = E_ERROR;
		errno = 0;
		set_dbms_error(me, d, err);
		goto exit_com;
	} else if (((cmd.token & MASK_TOKEN) != token) ||
		   ((cmd.token | F_SERVER_SIDE) == 0)) {
		err = E_PROTO;
		goto exit_com;
	};

	if ((rr1.data != NULL) && (rr1.size)) {
		(*me->free) (rr1.data);
		rr1.size = 0;
	};

	if ((rr2.data != NULL) && (rr2.size)) {
		(*me->free) (rr2.data);
		rr1.size = 0;
	};

	if ((cmd.token & MASK_STATUS) == F_FOUND) {
		if (retval)
			*retval = 0;
	} else {
		if (retval)
			*retval = 1;
		if (r1 != NULL) {
			if ((r1->size) && (r1->size))
				(*me->free) (r1->data);
			r1->data = NULL;
			r1->size = 0;
		};
		if (r2 != NULL) {
			if ((r2->size) && (r2->size))
				(*me->free) (r2->data);
			r2->data = NULL;
			r2->size = 0;
		};
	};

	err = 0;
	goto done_com;

retry_com:
exit_com:
	if ((r1 != NULL) && (r1->data != NULL) && (r1->size != 0)) {
		(*me->free) (r1->data);
		r1->size = 0;
	};

	if ((r2 != NULL) && (r2->data != NULL) && (r2->size != 0)) {
		(*me->free) (r2->data);
		r2->size = 0;
	};

	if ((rr1.data != NULL) && (rr1.size)) {
		(*me->free) (rr1.data);
		rr1.size = 0;
	};

	if ((rr2.data != NULL) && (rr1.size)) {
		(*me->free) (rr2.data);
		rr2.size = 0;
	};

done_com:

	return err;
}
Example #2
0
/*thread que recebe da camada de baixo*/
PRIVATE void *internalrecv(void *param)
{
    datagram_t *recv;
    pthread_t recv_route_thread;
    packlst_t *list = NULL;
    uint16_t rcv_checksum;
    byte *buf;
    size_t size;
    size_t data_size;
    while(TRUE)
    {
        rcv_checksum = 1;
        //espera por liberação da camada de enlace para o próximo recebimento        
        LOG("mutex travado para receber");
        pthread_mutex_lock(&net_recv_mutex);
        
        //copia dados recebidos pelo enlace
        buf = recv_frame.data;
        size = recv_frame.size;
        
        //libera camada de enlace para o proximo recebimento
        LOG("mutex liberado para camada de enlace");
        pthread_mutex_unlock(&link_recv_mutex);
        
        //criação do datagram_t
        recv = buildrecvdatagram(buf, size);
        LOG("recebendo data %s", recv->data);
        //recv = ALLOC(datagram_t, sizeof(datagram_t));
        //recv->data = ALLOC(byte, size - NET_HEADER_SIZE);
        //memcpy(recv, buf, NET_HEADER_SIZE - CHECKSUM_SIZE);
        //memcpy(recv->data, buf + NET_HEADER_SIZE - CHECKSUM_SIZE, size - NET_HEADER_SIZE);
        //memcpy(&recv->checksum, buf + size - CHECKSUM_SIZE, CHECKSUM_SIZE);
        
        //calcula o checksum
        //LOG("check: %u",recv->checksum);
        rcv_checksum = checksum(buf, size - CHECKSUM_SIZE);
        //LOG("checksum calculado: %#04x", rcv_checksum);
        rcv_checksum = rcv_checksum - recv->checksum;
        //LOG("resultado do checksum: %#04x", rcv_checksum);
        
        //desaloca buf
        free(buf);
        buf = NULL;
        
        //se o checksum estiver correto
        if (!rcv_checksum)
        {LOG("dest %d %d ", recv->dest, num_global);
            //se o destino é para mim
            if(recv->dest == num_global)
            {LOG("pack para mim");
                //adiciona na lista e se tiver completo trata o pacote
                if(insertoffset(&list, recv) == TRUE)
                {
                    if(list == NULL)
			         LOG("Esta 222 NULL ---------");
                    LOG("insertoffset ok!");
                    //tratar pacote
                    recv->data = getpack(&list, recv->id, recv->src, &data_size);
                    LOG("get pack");
                    LOG("recv->data %s", recv->data);
                    switch(recv->protocol)
                    {
                        case 0: //mensagem de rotas
                            pthread_create(&recv_route_thread, NULL, internalhandleroute, recv->data);
                            pthread_detach(recv_route_thread);
                            free(recv);
                            break;
                        case 1: //PTC
                        case 2:
                            //repassa o pacote para camada de transporte
                            
                            //espera por liberação da camada de transporte para o próximo recebimento
                            pthread_mutex_lock(&net2_recv_mutex);
                            LOG("mutex travado para repassar a camada de transporte");
                            recv_datagram.data = recv->data;
                            recv_datagram.size = data_size;
                            recv_datagram.src = recv->src;
                            LOG("data: %s", recv_datagram.data);
                            LOG("data: %zu", recv_datagram.size);
                            free(recv);
                            
                            //libera camada de transporte para pegar o pacote
                            LOG("mutex liberado para camada de transporte");
                            pthread_mutex_unlock(&transp_recv_mutex);
                            break;
                    }
                }
            }
            else //senão reenvia pacote
            {LOG("pack nao e para mim");
                //reenviar pacote
                recv->protocol = 2;
                recv->ttl--;
                net_resend(recv);
            }
        }
    }
}