Esempio n. 1
0
//TODO: make this function not suck.
static void doFriends(void)
{
    /* TODO: add incoming connections and some other stuff. */
    uint32_t i;
    int len;
    uint8_t temp[MAX_DATA_SIZE];
    for (i = 0; i < numfriends; ++i) {
        if (friendlist[i].status == FRIEND_ADDED) {
            int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
            if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
                set_friend_status(i, FRIEND_REQUESTED);
            else if (fr > 0)
                set_friend_status(i, FRIEND_REQUESTED);
        }
        if (friendlist[i].status == FRIEND_REQUESTED || friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */
            if (friendlist[i].status == FRIEND_REQUESTED) {
                if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
                    send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
                    friendlist[i].friend_request_id = unix_time();
                }
            }
            IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
            switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) {
            case 0:
                if (friendip.ip.i > 1)
                    friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
                break;
            case 3: /*  Connection is established */
                set_friend_status(i, FRIEND_ONLINE);
                friendlist[i].name_sent = 0;
                friendlist[i].userstatus_sent = 0;
                friendlist[i].statusmessage_sent = 0;
                break;
            case 4:
                crypto_kill(friendlist[i].crypt_connection_id);
                friendlist[i].crypt_connection_id = -1;
                break;
            default:
                break;
            }
        }
        while (friendlist[i].status == FRIEND_ONLINE) { /* friend is online */
            if (friendlist[i].name_sent == 0) {
                if (m_sendname(i, self_name, self_name_length))
                    friendlist[i].name_sent = 1;
            }
            if (friendlist[i].statusmessage_sent == 0) {
                if (send_statusmessage(i, self_statusmessage, self_statusmessage_length))
                    friendlist[i].statusmessage_sent = 1;
            }
            if (friendlist[i].userstatus_sent == 0) {
                if (send_userstatus(i, self_userstatus))
                    friendlist[i].userstatus_sent = 1;
            }
            len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
            uint8_t packet_id = temp[0];
            uint8_t* data = temp + 1;
            int data_length = len - 1;
            if (len > 0) {
                switch (packet_id) {
                case PACKET_ID_NICKNAME: {
                    if (data_length >= MAX_NAME_LENGTH || data_length == 0)
                        break;
                    if(friend_namechange_isset)
                        friend_namechange(i, data, data_length);
                    memcpy(friendlist[i].name, data, data_length);
                    friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */
                    break;
                }
                case PACKET_ID_STATUSMESSAGE: {
                    if (data_length == 0)
                        break;
                    uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1);
                    memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
                    if (friend_statusmessagechange_isset)
                        friend_statusmessagechange(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
                    set_friend_statusmessage(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH));
                    free(status);
                    break;
                }
                case PACKET_ID_USERSTATUS: {
                    if (data_length != 1)
                        break;
                    USERSTATUS status = data[0];
                    if (friend_userstatuschange_isset)
                        friend_userstatuschange(i, status);
                    set_friend_userstatus(i, status);
                    break;
                }
                case PACKET_ID_MESSAGE: {
                    uint8_t *message_id = data;
                    uint8_t message_id_length = 4;
                    uint8_t *message = data + message_id_length;
                    uint16_t message_length = data_length - message_id_length;
                    if (friendlist[i].receives_read_receipts) {
                        write_cryptpacket_id(i, PACKET_ID_RECEIPT, message_id, message_id_length);
                    }
                    if (friend_message_isset)
                        (*friend_message)(i, message, message_length);
                    break;
                }
                case PACKET_ID_ACTION: {
                    if (friend_action_isset)
                        (*friend_action)(i, data, data_length);
                    break;
                }
                case PACKET_ID_RECEIPT: {
                    uint32_t msgid;
                    if (data_length < sizeof(msgid))
                        break;
                    memcpy(&msgid, data, sizeof(msgid));
                    msgid = ntohl(msgid);
                    if (read_receipt_isset)
                        (*read_receipt)(i, msgid);
                    break;
                }
                }
            } else {
                if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
                    crypto_kill(friendlist[i].crypt_connection_id);
                    friendlist[i].crypt_connection_id = -1;
                    set_friend_status(i, FRIEND_CONFIRMED);
                }
                break;
            }
        }
    }
}
Esempio n. 2
0
//TODO: make this function not suck.
static void doFriends()
{
    /* TODO: add incoming connections and some other stuff. */
    uint32_t i;
    int len;
    uint8_t temp[MAX_DATA_SIZE];
    for (i = 0; i < numfriends; ++i) {
        if (friendlist[i].status == 1) {
            int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
            if (fr == 0) /* TODO: This needs to be fixed so that it sends the friend requests a couple of times in case of packet loss */
                friendlist[i].status = 2;
            else if (fr > 0)
                friendlist[i].status = 2;
        }
        if (friendlist[i].status == 2 || friendlist[i].status == 3) { /* friend is not online */
            if (friendlist[i].status == 2) {
                if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/
                    send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size);
                    friendlist[i].friend_request_id = unix_time();
                }
            }
            IP_Port friendip = DHT_getfriendip(friendlist[i].client_id);
            switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) {
            case 0:
                if (friendip.ip.i > 1)
                    friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip);
                break;
            case 3: /*  Connection is established */
                friendlist[i].status = 4;
                break;
            case 4:
                crypto_kill(friendlist[i].crypt_connection_id);
                friendlist[i].crypt_connection_id = -1;
                break;
            default:
                break;
            }
        }
        while (friendlist[i].status == 4) { /* friend is online */
            if (friendlist[i].name_sent == 0) {
                if (m_sendname(i, self_name, self_name_length))
                    friendlist[i].name_sent = 1;
            }
            if (friendlist[i].userstatus_sent == 0) {
                if (send_userstatus(i, self_userstatus, self_userstatus_len))
                    friendlist[i].userstatus_sent = 1;
            }
            len = read_cryptpacket(friendlist[i].crypt_connection_id, temp);
            if (len > 0) {
                switch (temp[0]) {
                case PACKET_ID_NICKNAME: {
                    if (len >= MAX_NAME_LENGTH + 1 || len == 1)
                        break;
                    if(friend_namechange_isset)
                        friend_namechange(i, temp + 1, len - 1);
                    memcpy(friendlist[i].name, temp + 1, len - 1);
                    friendlist[i].name[len - 2] = 0; /* make sure the NULL terminator is present. */
                    break;
                }
                case PACKET_ID_USERSTATUS: {
                    uint8_t *status = calloc(MIN(len - 1, MAX_USERSTATUS_LENGTH), 1);
                    memcpy(status, temp + 1, MIN(len - 1, MAX_USERSTATUS_LENGTH));
                    if (friend_statuschange_isset)
                        friend_statuschange(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
                    set_friend_userstatus(i, status, MIN(len - 1, MAX_USERSTATUS_LENGTH));
                    free(status);
                    break;
                }
                case PACKET_ID_MESSAGE: {
                    if (friend_message_isset)
                        (*friend_message)(i, temp + 1, len - 1);
                    break;
                }
                }
            } else {
                if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */
                    crypto_kill(friendlist[i].crypt_connection_id);
                    friendlist[i].crypt_connection_id = -1;
                    friendlist[i].status = 3;
                }
                break;
            }
        }
    }
}