Пример #1
0
// Get next auth manager message.
int authmgtGetNextMsg(struct s_authmgt *mgt, struct s_msg *out_msg, struct s_peeraddr *target) {
	int used = idspUsedCount(&mgt->idsp);
	int tnow = utilGetClock();
	int authstateid;
	int i;
    
	for(i=0; i<used; i++) {
		authstateid = idspNext(&mgt->idsp);
		if((tnow - mgt->lastrecv[authstateid]) >= AUTHMGT_RECV_TIMEOUT) { // check if auth session has expired
            authmgtDelete(mgt, authstateid);
            continue;
        }
        
        if((tnow - mgt->lastsend[authstateid]) <= AUTHMGT_RESEND_TIMEOUT) { // only send one auth message per specified time interval and session
            continue;
        }
        
        if(authGetNextMsg(&mgt->authstate[authstateid], out_msg)) {
            mgt->lastsend[authstateid] = tnow;
            *target = mgt->peeraddr[authstateid];
            
            CREATE_HUMAN_IP(target);
            debugf("[%d] New AUTH packet for %s created, size: %d", authstateid, humanIp, out_msg->len);
            
            return 1;
        }
    }
    
	return 0;
}
Пример #2
0
// Create new auth session. Returns ID of session if successful.
int authmgtNew(struct s_authmgt *mgt, const struct s_peeraddr *peeraddr) {
	int authstateid = idspNew(&mgt->idsp);
	int tnow = utilGetClock();
	
	if(authstateid < 0) {
		return -1;
	}

	mgt->lastsend[authstateid] = (mgt->fastauth) ? (tnow - authmgt_RESEND_TIMEOUT - 3) : tnow;
	mgt->lastrecv[authstateid] = tnow;
	mgt->peeraddr[authstateid] = *peeraddr;
    
    CREATE_HUMAN_IP(peeraddr);
    debugf("Starting new auth session for %s, ID: %d", humanIp, authstateid);
	
    return authstateid;
}
Пример #3
0
// Update NodeDB entry.
static void nodedbUpdate(struct s_nodedb *db, struct s_nodeid *nodeid, struct s_peeraddr *addr, const int update_lastseen, const int update_lastconnect, const int update_lastconntry) {
	int tnow = utilGetClock();
	struct s_map *addrset;
	struct s_map *newaddrset;
	struct s_nodedb_addrdata *addrdata;
	struct s_nodedb_addrdata addrdata_new;

	if(db != NULL && nodeid != NULL && addr != NULL) {
		addrset = mapGet(db->addrdb, nodeid->id);
		if(addrset == NULL) {
			newaddrset = mapGetValueByID(db->addrdb, mapAddReturnID(db->addrdb, nodeid->id, NULL));
			if(newaddrset != NULL) {
				if(mapMemInit(newaddrset, mapMemSize(db->num_peeraddrs, peeraddr_SIZE, sizeof(struct s_nodedb_addrdata)), db->num_peeraddrs, peeraddr_SIZE, sizeof(struct s_nodedb_addrdata))) {
					mapEnableReplaceOld(newaddrset);
					addrset = newaddrset;
				}
			}
		}

		if(addrset != NULL) {
			addrdata_new.lastseen = 0;
			addrdata_new.lastconnect = 0;
			addrdata_new.lastconntry = 0;
			addrdata_new.lastseen_t = 0;
			addrdata_new.lastconnect_t = 0;
			addrdata_new.lastconntry_t = 0;
			if((addrdata = mapGet(addrset, addr->addr)) != NULL) {
				addrdata_new = *addrdata;
			}
			if(update_lastseen > 0) {
				addrdata_new.lastseen = 1;
				addrdata_new.lastseen_t = tnow;
			}
			if(update_lastconnect > 0) {
				addrdata_new.lastconnect = 1;
				addrdata_new.lastconnect_t = tnow;
			}
			if(update_lastconntry > 0) {
				addrdata_new.lastconntry = 1;
				addrdata_new.lastconntry_t = tnow;
			}
			mapSet(addrset, addr->addr, &addrdata_new);
		}
	}
}
Пример #4
0
// Returns a NodeDB ID that matches the specified criteria.
static int nodedbGetDBID(struct s_nodedb *db, struct s_nodeid *nodeid, const int max_lastseen, const int max_lastconnect, const int min_lastconntry) {
	int i, i_max, nid, tnow, ret;
	tnow = utilGetClock();
	i_max = mapGetKeyCount(db->addrdb);
	ret = -1;
	if(nodeid == NULL) { // find DBID for any NodeID
		i = 0;
		while((i < i_max) && (ret < 0)) {
			nid = mapGetNextKeyID(db->addrdb);
			ret = nodedbGetDBIDByID(db, nid, tnow, max_lastseen, max_lastconnect, min_lastconntry);
			i++;
		}
	}
	else { // find DBID for specified NodeID
		nid = mapGetKeyID(db->addrdb, nodeid->id);
		if(!(nid < 0)) {
			ret = nodedbGetDBIDByID(db, nid, tnow, max_lastseen, max_lastconnect, min_lastconntry);
		}
	}
	return ret;
}
Пример #5
0
// Generate NodeDB status report.
static void nodedbStatus(struct s_nodedb *db, char *report, const int report_len) {
	int i;
	int j;
	int size;
	int rpsize;
	int pos;
	int tnow;
	unsigned char timediff[4];
	struct s_map *addrset;
	struct s_nodedb_addrdata *addrdata;

	tnow = utilGetClock();
	size = mapGetKeyCount(db->addrdb);
	rpsize = (95 * (1 + db->num_peeraddrs)) + 2;

	pos = 0;
	memcpy(&report[pos], "NodeID + Address                                                  LastSeen  LastConn  LastTry ", 94);
	pos = pos + 94;
	report[pos++] = '\n';

	i = 0;
	while(i < size && pos < (report_len - rpsize)) {
		if(mapIsValidID(db->addrdb, i)) {
			utilByteArrayToHexstring(&report[pos], ((nodeid_SIZE * 2) + 2), mapGetKeyByID(db->addrdb, i), nodeid_SIZE);
			pos = pos + (nodeid_SIZE * 2);
			addrset = mapGetValueByID(db->addrdb, i);
			memcpy(&report[pos], "                              ", 30);
			pos = pos + 30;
			j = 0;
			while(j < db->num_peeraddrs) {
				if(mapIsValidID(addrset, j)) {
					addrdata = mapGetValueByID(addrset, j);
					report[pos++] = '\n';
					memcpy(&report[pos], "            ", 12);
					pos = pos + 12;
					report[pos++] = '-';
					report[pos++] = '-';
					report[pos++] = '>';
					report[pos++] = ' ';
					utilByteArrayToHexstring(&report[pos], ((peeraddr_SIZE * 2) + 2), mapGetKeyByID(addrset, j), peeraddr_SIZE);
					pos = pos + (peeraddr_SIZE * 2);
					report[pos++] = ' ';
					report[pos++] = ' ';
					if(addrdata->lastseen) {
						utilWriteInt32(timediff, (tnow - addrdata->lastseen_t));
						utilByteArrayToHexstring(&report[pos], 10, timediff, 4);
					}
					else {
						memcpy(&report[pos], "--------", 8);
					}
					pos = pos + 8;
					report[pos++] = ' ';
					report[pos++] = ' ';
					if(addrdata->lastconnect) {
						utilWriteInt32(timediff, (tnow - addrdata->lastconnect_t));
						utilByteArrayToHexstring(&report[pos], 10, timediff, 4);
					}
					else {
						memcpy(&report[pos], "--------", 8);
					}
					pos = pos + 8;
					report[pos++] = ' ';
					report[pos++] = ' ';
					if(addrdata->lastconntry) {
						utilWriteInt32(timediff, (tnow - addrdata->lastconntry_t));
						utilByteArrayToHexstring(&report[pos], 10, timediff, 4);
					}
					else {
						memcpy(&report[pos], "--------", 8);
					}
					pos = pos + 8;
				}
				j++;
			}
			report[pos++] = '\n';
		}
		i++;
	}
	report[pos++] = '\0';
}
Пример #6
0
// Decode auth message. Returns 1 if message is accepted.
int authmgtDecodeMsg(struct s_authmgt *mgt, const unsigned char *msg, const int msg_len, const struct s_peeraddr *peeraddr) {
	int authid;
	int authstateid;
	int tnow = utilGetClock();
	int newsession;
	int dupid;
    
    CREATE_HUMAN_IP(peeraddr);
    
    debugf("[%s] AUTH message received", humanIp);
    
	if(msg_len <= 4) {
        debugf("[%s] Wrong AUTH message size: %d", humanIp, msg_len);
        return 0;
    }
    
    authid = utilReadInt32(msg);
    if(authid > 0) {
        // message belongs to existing auth session
        authstateid = (authid - 1);
        
        debugf("Found active auth session: %d", authstateid);
        if(authstateid >= idspSize(&mgt->idsp)) {
            debugf("[%s] wrong auth state ID", humanIp);
            return 0;
        }
        
        if(!authDecodeMsg(&mgt->authstate[authstateid], msg, msg_len)) {
            debugf("[%s] failed to decode AUTH message", humanIp);
            return 0;
        }
        
        mgt->lastrecv[authstateid] = tnow;
        mgt->peeraddr[authstateid] = *peeraddr;
        if(mgt->fastauth) {
            mgt->lastsend[authstateid] = (tnow - authmgt_RESEND_TIMEOUT - 3);
        }
        
        if((authIsAuthed(&mgt->authstate[authstateid])) && (!authIsCompleted(&mgt->authstate[authstateid]))) mgt->current_authed_id = authstateid;
        
        if((authIsCompleted(&mgt->authstate[authstateid])) && (!authIsPeerCompleted(&mgt->authstate[authstateid]))) {
            msgf("Host %s authorized", humanIp);
            mgt->current_completed_id = authstateid;
        }
        
        return 1;
    } else if(authid == 0) {
        debugf("starting new session for %s, authid: %d", humanIp, authid);
        // message requests new auth session
        dupid = authmgtFindAddr(mgt, peeraddr);
        
        // we already have this session
        if(dupid >= 0) {
            // auth session with same PeerAddr found.
            if(authIsPreauth(&mgt->authstate[dupid])) {
                return 0;
            }
        
            authmgtDelete(mgt, dupid);
        }
        
        authstateid = authmgtNew(mgt, peeraddr);
        if(authstateid < 0) {
            // all auth slots are full, search for unused sessions that can be replaced
            dupid = authmgtFindUnused(mgt);
            if(!(dupid < 0)) {
                authmgtDelete(mgt, dupid);
                authstateid = authmgtNew(mgt, peeraddr);
                debugf("new auth session started for %s, authstateid %d", humanIp, authstateid);
            }
        }
        
        if(!(authstateid < 0)) {
            if(authDecodeMsg(&mgt->authstate[authstateid], msg, msg_len)) {
                mgt->lastrecv[authstateid] = tnow;
                mgt->peeraddr[authstateid] = *peeraddr;
                if(mgt->fastauth) {
                    mgt->lastsend[authstateid] = (tnow - authmgt_RESEND_TIMEOUT - 3);
                }
                return 1;
            }
            else {
                authmgtDelete(mgt, authstateid);
            }
        }
        
    }
    
    return 0;
}