Beispiel #1
0
int
listall_node(json_t *jmsg)
{
	char		*uuid;
	char		*network_uuid;
	char		*response;
	size_t		 array_size;
	size_t		 i;
static	size_t		 total = 1;
	json_t		*js_nodes;
	json_t		*node;
	struct vnetwork	*vnet;

	if ((js_nodes = json_object_get(jmsg, "nodes")) == NULL) {
		jlog(L_ERROR, "json_object_get failed");
		return -1;
	}

	if ((array_size = json_array_size(js_nodes)) == 0) {
		jlog(L_ERROR, "json_array_size failed");
		return -1;
	}

	for (i = 0; i < array_size; i++) {

		if ((node = json_array_get(js_nodes, i)) == NULL) {
			jlog(L_ERROR, "json_array_get failed");
			return -1;
		}

		if (json_unpack(node, "{s:s}", "uuid", &uuid) == -1 ||
		    json_unpack(node, "{s:s}", "networkuuid", &network_uuid) == -1) {
			jlog(L_ERROR, "NULL parameter");
			return -1;
		}

		if ((vnet = vnetwork_lookup(network_uuid)) != NULL) {
			ctable_insert(vnet->atable, uuid, vnet->access_session);
		}
	}

	if ((json_unpack(jmsg, "{s:s}", "response", &response)) == -1) {
		jlog(L_ERROR, "json_unpack failed");
		return -1;
	}

	if (strcmp(response, "success") == 0) {
		jlog(L_DEBUG, "fetched %d node", total);
		return 0;
	}

	total++;
	return 1;
}
Beispiel #2
0
RpcConnection rpc_connect(char *host, unsigned short port,
                          char *svcName, unsigned long seqno) {
    ConnectPayload *buf;
    RpcEndpoint *nep;
    int len = sizeof(PayloadHeader) + 1;	/* room for '\0' */
    CRecord *cr;
    unsigned long subport;
    unsigned long states[2] = {ST_IDLE, ST_TIMEDOUT};
    unsigned long id = 0;

    ctable_lock();
    subport = ctable_newSubport();
    nep = rpc_socket(host, port, subport);
    if (nep != NULL) {
        id = gen_conn_id();
        len += strlen(svcName);			/* room for svcName */
        buf = (ConnectPayload *)malloc(len);
        cp_complete((ControlPayload *)buf, nep->subport, CONNECT, seqno, 1, 1);
        strcpy(buf->sname, svcName);
        cr = crecord_create(nep, seqno);
        crecord_setCID(cr, id);
        crecord_setPayload(cr, buf, len, ATTEMPTS, TICKS);
#ifdef LOG
        dumpsockNpacket(&(nep->addr), (DataPayload *)buf, "rpc_connect");
#endif /* LOG */
        (void) send_payload(nep, buf, len);
        crecord_setState(cr, ST_CONNECT_SENT);
        ctable_insert(cr);
        if (crecord_waitForState(cr, states, 2) == ST_TIMEDOUT) {
            ctable_remove(cr);
            crecord_destroy(cr);
            id = 0;
        }
        ctable_unlock();
    }
    return (RpcConnection)id;
}
Beispiel #3
0
/* Authentication Request from the node */
int
authRequest(struct session *session, DNDSMessage_t *req_msg)
{
	char		*certName = NULL;
	size_t	 	 length = 0;

	struct session *old_session = NULL;

	if (session->state != SESSION_STATE_NOT_AUTHED) {
		jlog(L_WARNING, "authRequest duplicate");
		return -1;
	}

	DNDSMessage_t *msg = NULL;

	DNDSMessage_new(&msg);
	DNDSMessage_set_channel(msg, 0);
	DNDSMessage_set_pdu(msg, pdu_PR_dnm);

	DNMessage_set_seqNumber(msg, 1);
	DNMessage_set_ackNumber(msg, 0);
	DNMessage_set_operation(msg, dnop_PR_authResponse);

	AuthRequest_get_certName(req_msg, &certName, &length);

	jlog(L_DEBUG, "URI:%s", certName);
	session->node_info = cn2node_info(certName);
	if (session->node_info == NULL) {
		jlog(L_WARNING, "cn2node_info failed");
		DNDSMessage_del(msg);
		return -1;
	}

//	jlog(L_DEBUG, "type: %s", session->node_info->type);
	jlog(L_DEBUG, "uuid: %s", session->node_info->uuid);
	jlog(L_DEBUG, "network_uuid: %s", session->node_info->network_uuid);
	jlog(L_DEBUG, "network_id: %s", session->node_info->network_id);
	jlog(L_DEBUG, "v: %d", session->node_info->v);

	if (session->node_info->v == 1) {
		session->vnetwork = vnetwork_lookup_id(session->node_info->network_id);
		if (session->vnetwork != NULL) {
			strncpy(session->node_info->network_uuid, session->vnetwork->uuid, 36);
			session->node_info->network_uuid[36] = '\0';
		}
	} else
		session->vnetwork = vnetwork_lookup(session->node_info->network_uuid);

	if (session->vnetwork == NULL) {
		AuthResponse_set_result(msg, DNDSResult_noRight);
		net_send_msg(session->netc, msg);
		DNDSMessage_del(msg);
		return -1;
	}

	/* check if the node's uuid is known
	if (ctable_find(session->context->atable, session->node_info->uuid) == NULL) {
		AuthResponse_set_result(msg, DNDSResult_noRight);
		net_send_msg(session->netc, msg);
		DNDSMessage_del(msg);
		jlog(L_ERROR, "authentication failed, invalid certificate");
		return -1;
	}
	*/

	/* check if the node is already connected */
	old_session = ctable_find(session->vnetwork->ctable, session->node_info->uuid);
//	if (old_session == NULL) {
		ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
/*
	} else {
		// that node is already connected, if the new session is from the same IP
		// disconnect the old session, and let this one connect
		if (old_session->ip == NULL) {
			net_disconnect(old_session->netc);
			ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
		} else if (strcmp(old_session->ip, session->ip) == 0) {
			net_disconnect(old_session->netc);
			ctable_insert(session->vnetwork->ctable, session->node_info->uuid, session);
		}
	}
*/

	session->cert_name = strdup(certName);
	if (session->netc->security_level == NET_UNSECURE) {

		AuthResponse_set_result(msg, DNDSResult_success);
		net_send_msg(session->netc, msg);

		session->state = SESSION_STATE_AUTHED;
		session->netc->on_secure(session->netc);

	} else {

		AuthResponse_set_result(msg, DNDSResult_secureStepUp);
		net_send_msg(session->netc, msg);

		krypt_add_passport(session->netc->kconn, session->vnetwork->passport);
		session->state = SESSION_STATE_WAIT_STEPUP;
		net_step_up(session->netc);
	}

	DNDSMessage_del(msg);

	return 0;
}
Beispiel #4
0
/* continuously reads messages from UDP port */
static void *reader(UNUSED void *args) {
    DataPayload *dp;
    char buf[10240];
    struct sockaddr_in c_addr;
    socklen_t len;
    int n;

    debugf("reader thread started\n");
    for(;;) {
        unsigned short cmd;
        unsigned long sb;
        unsigned long seqno;
        unsigned char fnum;
        unsigned char nfrags;
        char *sp;
        unsigned short pt;
        RpcEndpoint ep;
        CRecord *cr;

        len = sizeof(c_addr);
        memset(&c_addr, 0, len);
        n = recvfrom(my_sock, buf, sizeof(buf), 0,
                     (struct sockaddr *)&c_addr, &len);
        if (n < 0)
            continue;
        buf[n] = '\0';
        dp = (DataPayload *)buf;
        cmd = ntohs(dp->hdr.command);
        sb = ntohl(dp->hdr.subport);
        seqno = ntohl(dp->hdr.seqno);
        fnum = dp->hdr.fnum;
        nfrags = dp->hdr.nfrags;
        sp = inet_ntoa(c_addr.sin_addr);
        pt = ntohs(c_addr.sin_port);
        if (cmd >= CMD_LOW && cmd <= CMD_HIGH) {
            logf("%s from %s:%05u:%08lx; seqno = %ld, frag/nfrag = %u/%u\n",
                 cmdnames[cmd], sp, pt, sb, seqno, fnum, nfrags);
        } else {
            errorf("Illegal command received: %d\n", cmd);
            continue;
        }
        endpoint_complete(&ep, &c_addr, sb);
        ctable_lock();
        cr = ctable_look_ep(&ep);
        switch (cmd) {
        case CONNECT: {
            RpcEndpoint *nep;
            ConnectPayload *conp = (ConnectPayload *)dp;
            ControlPayload *p;
            int newcr = 0;
            SRecord *sr;
            sr = stable_lookup(conp->sname);
            if (sr == NULL)
                break;
            if (cr == NULL) {
                nep = endpoint_duplicate(&ep);
                cr = crecord_create(nep, seqno);
                crecord_setCID(cr, gen_conn_id());
                newcr = 1;
            } else if (cr->state != ST_IDLE) {
                fprintf(stderr,
                        "%s from %s:%05u:%08lx; seqno = %ld, frag/nfrag = %u/%u\n",
                        cmdnames[cmd], sp, pt, sb, seqno, fnum, nfrags);
                crecord_dump(cr, "connectrqst");
            }
            if (newcr || cr->state == ST_IDLE) {
                if (newcr) {
                    p = (ControlPayload *)malloc(CP_SIZE);
                    cp_complete(p, nep->subport, CACK, seqno, 1, 1);
                    crecord_setPayload(cr, p, CP_SIZE, ATTEMPTS, TICKS);
                }
                crecord_setService(cr, sr);
                (void) send_payload(cr->ep, cr->pl, cr->size);
                crecord_setState(cr, ST_IDLE);
            }
            if (newcr)
                ctable_insert(cr);
            break;
        }
        case CACK: {
            if ((cr != NULL)) {
                if (seqno == cr->seqno)
                    crecord_setState(cr, ST_IDLE);
            }
            break;
        }
#define NEW 2
#define OLD 1
#define ILL 0
        case QUERY: {
            DataPayload *p = NULL;
            ControlPayload *cp = NULL;
            int dplen, cplen;
            unsigned long state;
            int accept = ILL;

            if (cr == NULL)
                break;
            state = cr->state;
            if ((seqno - cr->seqno) == 1 &&
                    (state == ST_IDLE || state == ST_RESPONSE_SENT)) {
                accept = NEW;
                cr->seqno = seqno;
                p = (DataPayload *)malloc(n);
                dplen = n;
                memcpy(p, buf, n);
            } else if (seqno == cr->seqno && state == ST_FACK_SENT &&
                       (fnum - cr->lastFrag) == 1 &&
                       fnum == nfrags) {
                void *tp;
                unsigned short flen = ntohs(dp->dhdr.flen);
                accept = NEW;
                p = (DataPayload *)cr->resp;
                dplen = sizeof(PayloadHeader) + sizeof(DataHeader) +
                        ntohs(dp->dhdr.tlen);
                cr->resp = NULL;
                tp = (void *)&(p->data[FR_SIZE * (fnum - 1)]);
                memcpy(tp, dp->data, flen);
            } else if (seqno == cr->seqno &&
                       (state == ST_QACK_SENT || state == ST_RESPONSE_SENT)) {
                accept = OLD;
            }
            switch (accept) {
            case NEW:
                cplen = CP_SIZE;
                cp = (ControlPayload *)malloc(cplen);
                cp_complete(cp, ep.subport, QACK, seqno, fnum, nfrags);
                crecord_setPayload(cr, cp, cplen, ATTEMPTS, TICKS);
                (void)send_payload(cr->ep, cp, cplen);
                tsl_append(cr->svc->s_queue, cr->ep, p, dplen);
                crecord_setState(cr, ST_QACK_SENT);
                break;
            case OLD:
                (void)send_payload(cr->ep, cr->pl, cr->size);
                crecord_setState(cr, state);
                break;
            case ILL:
                break;
            }
            break;
        }
        case QACK: {
            if (cr != NULL) {
                if (seqno == cr->seqno)
                    crecord_setState(cr, ST_AWAITING_RESPONSE);
            }
            break;
        }
        case RESPONSE: {
            DataPayload *p = NULL;
            ControlPayload *cp = NULL;
            int cplen;
            unsigned long st;
            unsigned short flen = ntohs(dp->dhdr.flen);

            if (cr == NULL || seqno != cr->seqno)
                break;
            st = cr->state;
            if (st == ST_QUERY_SENT || st == ST_AWAITING_RESPONSE) {
                p = (DataPayload *)malloc(n);
                memcpy(p, buf, n);
                cr->resp = p;
            } else if (st == ST_FACK_SENT && (fnum - cr->lastFrag) == 1 &&
                       fnum == nfrags) {
                p = (DataPayload *)cr->resp;
                memcpy(&(p->data[FR_SIZE * (fnum -1)]), dp->data, flen);
                cr->lastFrag = fnum;
            } else
                break;
            cplen = CP_SIZE;
            cp = (ControlPayload *)malloc(cplen);
            cp_complete(cp, ep.subport, RACK, seqno, fnum, nfrags);
            crecord_setPayload(cr, cp, cplen, ATTEMPTS, TICKS);
            (void)send_payload(cr->ep, cp, cplen);
            crecord_setState(cr, ST_IDLE);
            break;
        }
        case RACK: {
            if (cr != NULL) {
                if (seqno == cr->seqno)
                    crecord_setState(cr, ST_IDLE);
            }
            break;
        }
        case DISCONNECT: {
            ControlPayload cp;		/* always send a DACK */

            cp_complete(&cp, ep.subport, DACK, seqno, 1, 1);
            (void)send_payload(&ep, &cp, CP_SIZE);
            if (cr != NULL) {
                crecord_setState(cr, ST_TIMEDOUT);
            }
            break;
        }
        case DACK: {
            if (cr != NULL) {
                if (seqno == cr->seqno)
                    crecord_setState(cr, ST_TIMEDOUT);
            }
            break;
        }
        case FRAGMENT: {
            DataPayload *p = NULL;
            ControlPayload *cp = NULL;
            int dplen, cplen;
            unsigned long st;
            int accept = ILL;
            unsigned short tlen = ntohs(dp->dhdr.tlen);
            unsigned short flen = ntohs(dp->dhdr.flen);
            int isQ, isR;

            if (cr == NULL)
                break;
            st = cr->state;
            isQ = (st == ST_IDLE || st == ST_RESPONSE_SENT) &&
                  (seqno - cr->seqno) == 1 && fnum == 1;
            isR = (st == ST_QUERY_SENT || st == ST_AWAITING_RESPONSE) &&
                  seqno == cr->seqno && fnum == 1;
            if (isQ || isR) {
                accept = NEW;
                cr->seqno = seqno;
                dplen = sizeof(PayloadHeader) + sizeof(DataHeader) + tlen;
                cr->resp = malloc(dplen);
                p = (DataPayload *)cr->resp;
                memcpy(p, buf, n);
            } else if (seqno == cr->seqno && st == ST_FACK_SENT &&
                       (fnum - cr->lastFrag) == 1) {
                void *tp;
                accept = NEW;
                p = (DataPayload *)cr->resp;
                tp = (void *)&(p->data[FR_SIZE * (fnum - 1)]);
                memcpy(tp, dp->data, flen);
            } else if (seqno == cr->seqno && st == ST_FACK_SENT &&
                       fnum == cr->lastFrag) {
                accept = OLD;
            }
            switch (accept) {
            case NEW:
                cr->lastFrag = fnum;
                cplen = CP_SIZE;
                cp = (ControlPayload *)malloc(cplen);
                cp_complete(cp, ep.subport, FACK, seqno, fnum, nfrags);
                crecord_setPayload(cr, cp, cplen, ATTEMPTS, TICKS);
                (void)send_payload(cr->ep, cp, cplen);
                crecord_setState(cr, ST_FACK_SENT);
                break;
            case OLD:
                (void)send_payload(cr->ep, cr->pl, cr->size);
                crecord_setState(cr, st);
                break;
            case ILL:
                break;
            }
            break;
        }
        case FACK: {
            if (cr != NULL) {
                if (seqno == cr->seqno && cr->state == ST_FRAGMENT_SENT
                        && fnum == cr->lastFrag) {
                    crecord_setState(cr, ST_FACK_RECEIVED);
                }
            }
            break;
        }
        case PING: {
            ControlPayload cp;

            if (cr != NULL) {
                cp_complete(&cp, ep.subport, PACK, seqno, 1, 1);
                (void)send_payload(&ep, &cp, CP_SIZE);
            }
            break;
        }
        case PACK: {
            if (cr != NULL) {
                crecord_setState(cr, cr->state);	/* resets ping data */
            }
            break;
        }
        case SEQNO: {
            ControlPayload *cp;

            if (cr != NULL) {
                unsigned long st = cr->state;
                if (st == ST_IDLE || st == ST_RESPONSE_SENT) {
                    cp = (ControlPayload *)malloc(CP_SIZE);
                    cp_complete(cp, ep.subport, SACK, seqno, 1, 1);
                    crecord_setPayload(cr, cp, CP_SIZE, ATTEMPTS, TICKS);
                    (void)send_payload(cr->ep, cp, CP_SIZE);
                    cr->seqno = seqno;
                    crecord_setState(cr, ST_IDLE);
                }
            }
            break;
        }
        case SACK: {
            if (cr != NULL && cr->state == ST_SEQNO_SENT) {
                crecord_setState(cr, ST_IDLE);
            }
            break;
        }
        default: {
            break;
        }
        }
        ctable_unlock();
    }
    return NULL;
}