mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' of https://github.com/dubslow/toxcore
This commit is contained in:
commit
80fdfbad07
|
@ -127,16 +127,16 @@ complete API documentation is available in `tox.h`.
|
|||
|
||||
|
||||
```
|
||||
#define TOX_MAX_AVATAR_DATA_LENGTH 16384
|
||||
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
|
||||
#define TOX_AVATAR_HASH_LENGTH 32
|
||||
|
||||
|
||||
/* Data formats for user avatar images */
|
||||
typedef enum {
|
||||
TOX_AVATARFORMAT_NONE,
|
||||
TOX_AVATARFORMAT_PNG
|
||||
TOX_AVATAR_FORMAT_NONE,
|
||||
TOX_AVATAR_FORMAT_PNG
|
||||
}
|
||||
TOX_AVATARFORMAT;
|
||||
TOX_AVATAR_FORMAT;
|
||||
|
||||
|
||||
|
||||
|
@ -287,11 +287,11 @@ functions. For a complete, working, example, see `testing/test_avatars.c`.
|
|||
In this example `load_data_file` is just an hypothetical function that loads
|
||||
data from a file into the buffer and sets the length accordingly.
|
||||
|
||||
uint8_t buf[TOX_MAX_AVATAR_DATA_LENGTH];
|
||||
uint8_t buf[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
uint32_t len;
|
||||
|
||||
if (load_data_file("avatar.png", buf, &len) == 0)
|
||||
if (tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, buf, len) != 0)
|
||||
if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_PNG, buf, len) != 0)
|
||||
fprintf(stderr, "Failed to set avatar.\n");
|
||||
|
||||
If the user is connected, this function will also notify all connected
|
||||
|
@ -306,9 +306,9 @@ notifications and unnecessary data transfers.
|
|||
|
||||
#### Removing the avatar from the current user
|
||||
|
||||
To remove an avatar, an application must set it to `TOX_AVATARFORMAT_NONE`.
|
||||
To remove an avatar, an application must set it to `TOX_AVATAR_FORMAT_NONE`.
|
||||
|
||||
tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
||||
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||
|
||||
If the user is connected, this function will also notify all connected
|
||||
friends about the avatar change.
|
||||
|
@ -362,7 +362,7 @@ checks the local avatar cache and emits an avatar data request if necessary:
|
|||
{
|
||||
printf("Receiving avatar information from friend %d. Format = %d\n",
|
||||
friendnumber, format);
|
||||
if (format = TOX_AVATARFORMAT_NONE) {
|
||||
if (format = TOX_AVATAR_FORMAT_NONE) {
|
||||
/* User have no avatar or removed the avatar */
|
||||
delete_avatar_from_cache(tox, friendnumber);
|
||||
} else {
|
||||
|
@ -382,7 +382,7 @@ cache:
|
|||
static void avatar_data_cb(Tox *tox, int32_t friendnumber, uint8_t format,
|
||||
uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
||||
{
|
||||
if (format = TOX_AVATARFORMAT_NONE) {
|
||||
if (format = TOX_AVATAR_FORMAT_NONE) {
|
||||
/* User have no avatar or removed the avatar */
|
||||
delete_avatar_from_cache(tox, friendnumber);
|
||||
} else {
|
||||
|
@ -453,8 +453,8 @@ the following structure:
|
|||
|
||||
Where 'format' is the image data format, one of the following:
|
||||
|
||||
0 = AVATARFORMAT_NONE (no avatar set)
|
||||
1 = AVATARFORMAT_PNG
|
||||
0 = AVATAR_FORMAT_NONE (no avatar set)
|
||||
1 = AVATAR_FORMAT_PNG
|
||||
|
||||
and 'hash' is the SHA-256 message digest of the avatar data.
|
||||
|
||||
|
@ -481,8 +481,8 @@ types.
|
|||
return, which semantics are explained bellow. The following values are
|
||||
defined:
|
||||
|
||||
0 = AVATARDATACONTROL_REQ
|
||||
1 = AVATARDATACONTROL_ERROR
|
||||
0 = AVATAR_DATACONTROL_REQ
|
||||
1 = AVATAR_DATACONTROL_ERROR
|
||||
|
||||
|
||||
- Packet `PACKET_ID_AVATAR_DATA_START` have the following format:
|
||||
|
@ -511,17 +511,17 @@ from a client "B":
|
|||
- "A" must initialize its control structures and mark its data transfer
|
||||
as not yet started. Then it requests avatar data from "B" by sending a
|
||||
packet `PACKET_ID_AVATAR_DATA_CONTROL` with 'op' set to
|
||||
`AVATARDATACONTROL_REQ`.
|
||||
`AVATAR_DATACONTROL_REQ`.
|
||||
|
||||
- If "B" accepts this transfer, it answers by sending an
|
||||
`PACKET_ID_AVATAR_DATA_START` with the fields 'format', 'hash' and
|
||||
'data_length' set to the respective values from the current avatar.
|
||||
If "B" have no avatar set, 'format' must be `AVATARFORMAT_NONE`, 'hash'
|
||||
If "B" have no avatar set, 'format' must be `AVATAR_FORMAT_NONE`, 'hash'
|
||||
must be zeroed and 'data_length' must be zero.
|
||||
|
||||
If "B" does not accept sending the avatar, it may send a packet
|
||||
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
||||
`AVATARDATACONTROL_ERROR` or simply ignore this request. "A" must cope
|
||||
`AVATAR_DATACONTROL_ERROR` or simply ignore this request. "A" must cope
|
||||
with this.
|
||||
|
||||
If "B" have an avatar, it sends a variable number of
|
||||
|
@ -531,7 +531,7 @@ from a client "B":
|
|||
- Upon receiving a `PACKET_ID_AVATAR_DATA_START`, "A" checks if it
|
||||
has sent a data request to "B". If not, just ignores the packet.
|
||||
|
||||
If "A" really requested avatar data and the format is `AVATARFORMAT_NONE`,
|
||||
If "A" really requested avatar data and the format is `AVATAR_FORMAT_NONE`,
|
||||
it triggers the avatar data callback, and clears all the temporary data,
|
||||
finishing the process. For other formats, "A" just waits for packets
|
||||
of type `PACKET_ID_AVATAR_DATA_PUSH`.
|
||||
|
@ -541,9 +541,9 @@ from a client "B":
|
|||
already received. If this conditions are valid, it checks if the total
|
||||
length of the data already stored in the receiving buffer plus the data
|
||||
present in the push packet is still less or equal than
|
||||
`TOX_MAX_AVATAR_DATA_LENGTH`. If invalid, it replies with a
|
||||
`TOX_AVATAR_MAX_DATA_LENGTH`. If invalid, it replies with a
|
||||
`PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op' set to
|
||||
`AVATARDATACONTROL_ERROR`.
|
||||
`AVATAR_DATACONTROL_ERROR`.
|
||||
|
||||
If valid, "A" updates the 'bytes_received' counter and concatenates the
|
||||
newly arrived data to the buffer.
|
||||
|
@ -566,7 +566,7 @@ from a client "B":
|
|||
some transfer limit for the data it sends.
|
||||
|
||||
- Any peer receiving a `PACKET_ID_AVATAR_DATA_CONTROL` with the field 'op'
|
||||
set to `AVATARDATACONTROL_ERROR` clears any existing control state and
|
||||
set to `AVATAR_DATACONTROL_ERROR` clears any existing control state and
|
||||
finishes sending or receiving data.
|
||||
|
||||
|
||||
|
@ -596,7 +596,7 @@ The present proposal mitigates this situation by:
|
|||
same offset of the avatar again and again, the implementation limits
|
||||
the amount of data a single user can request for some time. For now,
|
||||
the library will not allow an user to request more than
|
||||
`10*TOX_MAX_AVATAR_DATA_LENGTH` in less than 20 minutes;
|
||||
`10*TOX_AVATAR_MAX_DATA_LENGTH` in less than 20 minutes;
|
||||
|
||||
- Making the requester responsible for storing partial data and state
|
||||
information;
|
||||
|
|
|
@ -86,8 +86,8 @@ typedef struct {
|
|||
|
||||
static const def_avatar_name_t def_avatar_names[] = {
|
||||
/* In order of preference */
|
||||
{ TOX_AVATARFORMAT_PNG, "png", "avatar.png" },
|
||||
{ TOX_AVATARFORMAT_NONE, NULL, NULL }, /* Must be the last one */
|
||||
{ TOX_AVATAR_FORMAT_PNG, "png", "avatar.png" },
|
||||
{ TOX_AVATAR_FORMAT_NONE, NULL, NULL }, /* Must be the last one */
|
||||
};
|
||||
|
||||
|
||||
|
@ -99,7 +99,7 @@ static char *get_avatar_suffix_from_format(uint8_t format)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++)
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++)
|
||||
if (def_avatar_names[i].format == format)
|
||||
return def_avatar_names[i].suffix;
|
||||
|
||||
|
@ -118,7 +118,7 @@ static int load_avatar_data(char *fname, uint8_t *buf)
|
|||
if (fp == NULL)
|
||||
return -1; /* Error */
|
||||
|
||||
size_t n = fread(buf, 1, TOX_MAX_AVATAR_DATA_LENGTH, fp);
|
||||
size_t n = fread(buf, 1, TOX_AVATAR_MAX_DATA_LENGTH, fp);
|
||||
int ret;
|
||||
|
||||
if (ferror(fp) != 0 || n == 0)
|
||||
|
@ -222,7 +222,7 @@ static int load_user_avatar(Tox *tox, char *base_dir, int friendnum,
|
|||
}
|
||||
|
||||
*datalen = ret;
|
||||
tox_avatar_hash(tox, hash, data, *datalen);
|
||||
tox_hash(tox, hash, data, *datalen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ static int delete_user_avatar(Tox *tox, char *base_dir, int friendnum)
|
|||
/* This iteration is dumb and inefficient */
|
||||
int i;
|
||||
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATARFORMAT_NONE; i++) {
|
||||
for (i = 0; def_avatar_names[i].format != TOX_AVATAR_FORMAT_NONE; i++) {
|
||||
int ret = make_avatar_file_name(path, sizeof(path), base_dir,
|
||||
def_avatar_names[i].format, addr);
|
||||
|
||||
|
@ -305,7 +305,7 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
|
|||
char *base_dir = (char *) ud;
|
||||
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
||||
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
||||
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||
|
||||
if (tox_get_client_id(tox, n, addr) == 0) {
|
||||
byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
|
||||
|
@ -315,10 +315,10 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
|
|||
printf("Receiving avatar information from friend number %u.\n", n);
|
||||
}
|
||||
|
||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
||||
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||
DEBUG("format=%u, hash=%s", format, hash_str);
|
||||
|
||||
if (format == TOX_AVATARFORMAT_NONE) {
|
||||
if (format == TOX_AVATAR_FORMAT_NONE) {
|
||||
printf(" -> User do not have an avatar.\n");
|
||||
/* User have no avatar anymore, delete it from our cache */
|
||||
delete_user_avatar(tox, base_dir, n);
|
||||
|
@ -332,14 +332,14 @@ static void friend_avatar_info_cb(Tox *tox, int32_t n, uint8_t format, uint8_t *
|
|||
* these events.
|
||||
*/
|
||||
uint32_t cur_av_len;
|
||||
uint8_t cur_av_data[TOX_MAX_AVATAR_DATA_LENGTH];
|
||||
uint8_t cur_av_hash[TOX_AVATAR_HASH_LENGTH];
|
||||
uint8_t cur_av_data[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
uint8_t cur_av_hash[TOX_HASH_LENGTH];
|
||||
int ret;
|
||||
|
||||
ret = load_user_avatar(tox, base_dir, n, format, cur_av_hash, cur_av_data, &cur_av_len);
|
||||
|
||||
if (ret != 0
|
||||
&& memcpy(cur_av_hash, hash, TOX_AVATAR_HASH_LENGTH) != 0) {
|
||||
&& memcpy(cur_av_hash, hash, TOX_HASH_LENGTH) != 0) {
|
||||
printf(" -> Cached avatar is outdated. Requesting avatar data.\n");
|
||||
tox_request_avatar_data(tox, n);
|
||||
} else {
|
||||
|
@ -355,7 +355,7 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
|
|||
char *base_dir = (char *) ud;
|
||||
uint8_t addr[TOX_CLIENT_ID_SIZE];
|
||||
char addr_str[2 * TOX_CLIENT_ID_SIZE + 1];
|
||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
||||
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||
|
||||
if (tox_get_client_id(tox, n, addr) == 0) {
|
||||
byte_to_hex_str(addr, TOX_CLIENT_ID_SIZE, addr_str);
|
||||
|
@ -365,12 +365,12 @@ static void friend_avatar_data_cb(Tox *tox, int32_t n, uint8_t format,
|
|||
printf("Receiving avatar data from friend number %u.\n", n);
|
||||
}
|
||||
|
||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
||||
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||
DEBUG("format=%u, datalen=%d, hash=%s\n", format, datalen, hash_str);
|
||||
|
||||
delete_user_avatar(tox, base_dir, n);
|
||||
|
||||
if (format != TOX_AVATARFORMAT_NONE) {
|
||||
if (format != TOX_AVATAR_FORMAT_NONE) {
|
||||
int ret = save_user_avatar(tox, base_dir, n, format, data, datalen);
|
||||
|
||||
if (ret == 0)
|
||||
|
@ -406,7 +406,7 @@ static void friend_msg_cb(Tox *tox, int n, const uint8_t *msg, uint16_t len, voi
|
|||
set_avatar(tox, base_dir);
|
||||
reply_ptr = "Setting image avatar";
|
||||
} else if (strstr(msg_str, "!remove-avatar") != NULL) {
|
||||
int r = tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
||||
int r = tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||
DEBUG("tox_set_avatar returned %d", r);
|
||||
reply_ptr = "Removing avatar";
|
||||
}
|
||||
|
@ -453,10 +453,10 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
|
|||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp != NULL) {
|
||||
uint8_t buf[2 * TOX_MAX_AVATAR_DATA_LENGTH];
|
||||
uint8_t buf[2 * TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
int len = fread(buf, 1, sizeof(buf), fp);
|
||||
|
||||
if (len >= 0 && len <= TOX_MAX_AVATAR_DATA_LENGTH) {
|
||||
if (len >= 0 && len <= TOX_AVATAR_MAX_DATA_LENGTH) {
|
||||
int r = tox_set_avatar(tox, an->format, buf, len);
|
||||
DEBUG("%d bytes, tox_set_avatar returned=%d", len, r);
|
||||
|
||||
|
@ -468,7 +468,7 @@ static int try_avatar_file(Tox *tox, const char *base_dir, const def_avatar_name
|
|||
DEBUG("read error %d", len);
|
||||
} else {
|
||||
printf("Avatar file %s if too big (more than %d bytes)",
|
||||
path, TOX_MAX_AVATAR_DATA_LENGTH);
|
||||
path, TOX_AVATAR_MAX_DATA_LENGTH);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
@ -486,8 +486,8 @@ static void set_avatar(Tox *tox, const char *base_dir)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (def_avatar_names[i].format == TOX_AVATARFORMAT_NONE) {
|
||||
tox_set_avatar(tox, TOX_AVATARFORMAT_NONE, NULL, 0);
|
||||
if (def_avatar_names[i].format == TOX_AVATAR_FORMAT_NONE) {
|
||||
tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0);
|
||||
printf("No avatar file found, setting to NONE.\n");
|
||||
return;
|
||||
} else {
|
||||
|
@ -504,15 +504,15 @@ static void set_avatar(Tox *tox, const char *base_dir)
|
|||
static void print_avatar_info(Tox *tox)
|
||||
{
|
||||
uint8_t format;
|
||||
uint8_t data[TOX_MAX_AVATAR_DATA_LENGTH];
|
||||
uint8_t hash[TOX_AVATAR_HASH_LENGTH];
|
||||
uint8_t data[TOX_AVATAR_MAX_DATA_LENGTH];
|
||||
uint8_t hash[TOX_HASH_LENGTH];
|
||||
uint32_t data_length;
|
||||
char hash_str[2 * TOX_AVATAR_HASH_LENGTH + 1];
|
||||
char hash_str[2 * TOX_HASH_LENGTH + 1];
|
||||
|
||||
int ret = tox_get_self_avatar(tox, &format, data, &data_length, sizeof(data), hash);
|
||||
DEBUG("tox_get_self_avatar returned %d", ret);
|
||||
DEBUG("format: %d, data_length: %d", format, data_length);
|
||||
byte_to_hex_str(hash, TOX_AVATAR_HASH_LENGTH, hash_str);
|
||||
byte_to_hex_str(hash, TOX_HASH_LENGTH, hash_str);
|
||||
DEBUG("hash: %s", hash_str);
|
||||
}
|
||||
|
||||
|
|
|
@ -576,10 +576,10 @@ int m_set_userstatus(Messenger *m, uint8_t status)
|
|||
|
||||
int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t length)
|
||||
{
|
||||
if (length > MAX_AVATAR_DATA_LENGTH)
|
||||
if (length > AVATAR_MAX_DATA_LENGTH)
|
||||
return -1;
|
||||
|
||||
if (format == AVATARFORMAT_NONE) {
|
||||
if (format == AVATAR_FORMAT_NONE) {
|
||||
free(m->avatar_data);
|
||||
m->avatar_data = NULL;
|
||||
m->avatar_data_length = 0;
|
||||
|
@ -632,15 +632,18 @@ int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_
|
|||
return 0;
|
||||
}
|
||||
|
||||
int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||
int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||
{
|
||||
if (hash == NULL)
|
||||
return -1;
|
||||
|
||||
crypto_hash_sha256(hash, data, datalen);
|
||||
return 0;
|
||||
return crypto_hash_sha256(hash, data, datalen);
|
||||
}
|
||||
|
||||
int m_avatar_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||
{
|
||||
return m_hash(hash, data, datalen);
|
||||
}
|
||||
|
||||
int m_request_avatar_info(const Messenger *m, const int32_t friendnumber)
|
||||
{
|
||||
|
@ -673,10 +676,10 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
|
|||
if (friend_not_valid(m, friendnumber))
|
||||
return -1;
|
||||
|
||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
|
||||
if (avrd == NULL) {
|
||||
avrd = calloc(sizeof(AVATARRECEIVEDATA), 1);
|
||||
avrd = calloc(sizeof(AVATAR_RECEIVEDATA), 1);
|
||||
|
||||
if (avrd == NULL)
|
||||
return -1;
|
||||
|
@ -693,9 +696,9 @@ int m_request_avatar_data(const Messenger *m, const int32_t friendnumber)
|
|||
avrd->started = 0;
|
||||
avrd->bytes_received = 0;
|
||||
avrd->total_length = 0;
|
||||
avrd->format = AVATARFORMAT_NONE;
|
||||
avrd->format = AVATAR_FORMAT_NONE;
|
||||
|
||||
return send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_REQ);
|
||||
return send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_REQ);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2006,7 +2009,7 @@ Messenger *new_messenger(Messenger_Options *options)
|
|||
m->net = new_networking(ip, TOX_PORT_DEFAULT);
|
||||
}
|
||||
|
||||
m->avatar_format = AVATARFORMAT_NONE;
|
||||
m->avatar_format = AVATAR_FORMAT_NONE;
|
||||
m->avatar_data = NULL;
|
||||
|
||||
if (m->net == NULL) {
|
||||
|
@ -2159,17 +2162,17 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
|||
LOGGER_DEBUG("Error: PACKET_ID_AVATAR_DATA_CONTROL with bad "
|
||||
"data_length = %u, friendnumber = %u",
|
||||
data_length, friendnumber);
|
||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
||||
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||
return -1; /* Error */
|
||||
}
|
||||
|
||||
LOGGER_DEBUG("friendnumber = %u, op = %u", friendnumber, data[0]);
|
||||
|
||||
switch (data[0]) {
|
||||
case AVATARDATACONTROL_REQ: {
|
||||
case AVATAR_DATACONTROL_REQ: {
|
||||
|
||||
/* Check data transfer limits for this friend */
|
||||
AVATARSENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
|
||||
AVATAR_SENDDATA *const avsd = &(m->friendlist[friendnumber].avatar_send_data);
|
||||
|
||||
if (avsd->bytes_sent >= AVATAR_DATA_TRANSFER_LIMIT) {
|
||||
/* User reached data limit. Check timeout */
|
||||
|
@ -2183,7 +2186,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
|||
/* Friend still rate-limitted. Send an error and stops. */
|
||||
LOGGER_DEBUG("Avatar data transfer limit reached. "
|
||||
"friendnumber = %u", friendnumber);
|
||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
||||
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -2211,12 +2214,12 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
|||
if (!ret) {
|
||||
/* Something went wrong, try to signal the error so the friend
|
||||
* can clear up the state. */
|
||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
||||
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* User have no avatar data, nothing more to do. */
|
||||
if (m->avatar_format == AVATARFORMAT_NONE)
|
||||
if (m->avatar_format == AVATAR_FORMAT_NONE)
|
||||
return 0;
|
||||
|
||||
/* Send the actual avatar data. */
|
||||
|
@ -2241,7 +2244,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
|||
LOGGER_DEBUG("write_cryptpacket_id failed. ret = %d, "
|
||||
"friendnumber = %u, offset = %u",
|
||||
ret, friendnumber, offset);
|
||||
send_avatar_data_control(m, friendnumber, AVATARDATACONTROL_ERROR);
|
||||
send_avatar_data_control(m, friendnumber, AVATAR_DATACONTROL_ERROR);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -2249,7 +2252,7 @@ static int handle_avatar_data_control(Messenger *m, uint32_t friendnumber,
|
|||
return 0;
|
||||
}
|
||||
|
||||
case AVATARDATACONTROL_ERROR: {
|
||||
case AVATAR_DATACONTROL_ERROR: {
|
||||
if (m->friendlist[friendnumber].avatar_recv_data) {
|
||||
/* We were receiving the data, sender detected an error
|
||||
(eg. changing avatar) and asked us to stop. */
|
||||
|
@ -2276,7 +2279,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
|||
return -1;
|
||||
}
|
||||
|
||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
|
||||
if (avrd == NULL) {
|
||||
LOGGER_DEBUG("Received an unrequested DATA_START, friendnumber = %u",
|
||||
|
@ -2307,7 +2310,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
|||
friendnumber, avrd->format, avrd->total_length,
|
||||
avrd->bytes_received);
|
||||
|
||||
if (avrd->total_length > MAX_AVATAR_DATA_LENGTH) {
|
||||
if (avrd->total_length > AVATAR_MAX_DATA_LENGTH) {
|
||||
/* Invalid data length. Stops. */
|
||||
LOGGER_DEBUG("Error: total_length > MAX_AVATAR_DATA_LENGTH, "
|
||||
"friendnumber = %u", friendnumber);
|
||||
|
@ -2317,7 +2320,7 @@ static int handle_avatar_data_start(Messenger *m, uint32_t friendnumber,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (avrd->format == AVATARFORMAT_NONE || avrd->total_length == 0) {
|
||||
if (avrd->format == AVATAR_FORMAT_NONE || avrd->total_length == 0) {
|
||||
/* No real data to receive. Run callback function and finish. */
|
||||
LOGGER_DEBUG("format == NONE, friendnumber = %u", friendnumber);
|
||||
|
||||
|
@ -2343,7 +2346,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
|
|||
{
|
||||
LOGGER_DEBUG("friendnumber = %u, data_length = %u", friendnumber, data_length);
|
||||
|
||||
AVATARRECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
AVATAR_RECEIVEDATA *avrd = m->friendlist[friendnumber].avatar_recv_data;
|
||||
|
||||
if (avrd == NULL) {
|
||||
/* No active transfer. It must be an error or a malicious request,
|
||||
|
@ -2363,7 +2366,7 @@ static int handle_avatar_data_push(Messenger *m, uint32_t friendnumber,
|
|||
uint32_t new_length = avrd->bytes_received + data_length;
|
||||
|
||||
if (new_length > avrd->total_length
|
||||
|| new_length >= MAX_AVATAR_DATA_LENGTH) {
|
||||
|| new_length >= AVATAR_MAX_DATA_LENGTH) {
|
||||
/* Invalid data length due to error or malice. Stops. */
|
||||
LOGGER_DEBUG("Invalid data length. friendnumber = %u, "
|
||||
"new_length = %u, avrd->total_length = %u",
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
#define MAX_NAME_LENGTH 128
|
||||
/* TODO: this must depend on other variable. */
|
||||
#define MAX_STATUSMESSAGE_LENGTH 1007
|
||||
#define MAX_AVATAR_DATA_LENGTH 16384
|
||||
#define AVATAR_HASH_LENGTH 32
|
||||
#define AVATAR_MAX_DATA_LENGTH 16384
|
||||
#define AVATAR_HASH_LENGTH crypto_hash_sha256_BYTES
|
||||
|
||||
|
||||
#define FRIEND_ADDRESS_SIZE (crypto_box_PUBLICKEYBYTES + sizeof(uint32_t) + sizeof(uint16_t))
|
||||
|
@ -121,7 +121,7 @@ enum {
|
|||
#define AVATAR_DATA_MAX_CHUNK_SIZE (MAX_CRYPTO_DATA_SIZE-1)
|
||||
|
||||
/* Per-friend data limit for avatar data requests */
|
||||
#define AVATAR_DATA_TRANSFER_LIMIT (10*MAX_AVATAR_DATA_LENGTH)
|
||||
#define AVATAR_DATA_TRANSFER_LIMIT (10*AVATAR_MAX_DATA_LENGTH)
|
||||
#define AVATAR_DATA_TRANSFER_TIMEOUT (60) /* 164kB every 60 seconds is not a lot */
|
||||
|
||||
|
||||
|
@ -137,40 +137,40 @@ typedef enum {
|
|||
}
|
||||
USERSTATUS;
|
||||
|
||||
/* AVATARFORMAT -
|
||||
/* AVATAR_FORMAT -
|
||||
* Data formats for user avatar images
|
||||
*/
|
||||
typedef enum {
|
||||
AVATARFORMAT_NONE,
|
||||
AVATARFORMAT_PNG
|
||||
AVATAR_FORMAT_NONE = 0,
|
||||
AVATAR_FORMAT_PNG
|
||||
}
|
||||
AVATARFORMAT;
|
||||
AVATAR_FORMAT;
|
||||
|
||||
/* AVATARDATACONTROL
|
||||
/* AVATAR_DATACONTROL
|
||||
* To control avatar data requests (PACKET_ID_AVATAR_DATA_CONTROL)
|
||||
*/
|
||||
typedef enum {
|
||||
AVATARDATACONTROL_REQ,
|
||||
AVATARDATACONTROL_ERROR
|
||||
AVATAR_DATACONTROL_REQ,
|
||||
AVATAR_DATACONTROL_ERROR
|
||||
}
|
||||
AVATARDATACONTROL;
|
||||
AVATAR_DATACONTROL;
|
||||
|
||||
typedef struct {
|
||||
uint8_t started;
|
||||
AVATARFORMAT format;
|
||||
AVATAR_FORMAT format;
|
||||
uint8_t hash[AVATAR_HASH_LENGTH];
|
||||
uint32_t total_length;
|
||||
uint32_t bytes_received;
|
||||
uint8_t data[MAX_AVATAR_DATA_LENGTH];
|
||||
uint8_t data[AVATAR_MAX_DATA_LENGTH];
|
||||
}
|
||||
AVATARRECEIVEDATA;
|
||||
AVATAR_RECEIVEDATA;
|
||||
|
||||
typedef struct {
|
||||
/* Fields only used to limit the network usage from a given friend */
|
||||
uint32_t bytes_sent; /* Total bytes send to this user */
|
||||
uint64_t last_reset; /* Time the data counter was last reset */
|
||||
}
|
||||
AVATARSENDDATA;
|
||||
AVATAR_SENDDATA;
|
||||
|
||||
|
||||
struct File_Transfers {
|
||||
|
@ -230,8 +230,8 @@ typedef struct {
|
|||
int invited_groups[MAX_INVITED_GROUPS];
|
||||
uint16_t invited_groups_num;
|
||||
|
||||
AVATARSENDDATA avatar_send_data;
|
||||
AVATARRECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
|
||||
AVATAR_SENDDATA avatar_send_data;
|
||||
AVATAR_RECEIVEDATA *avatar_recv_data; // We are receiving avatar data from this friend.
|
||||
|
||||
struct {
|
||||
int (*function)(void *object, const uint8_t *data, uint32_t len);
|
||||
|
@ -264,7 +264,7 @@ typedef struct Messenger {
|
|||
|
||||
USERSTATUS userstatus;
|
||||
|
||||
AVATARFORMAT avatar_format;
|
||||
AVATAR_FORMAT avatar_format;
|
||||
uint8_t *avatar_data;
|
||||
uint32_t avatar_data_length;
|
||||
uint8_t avatar_hash[AVATAR_HASH_LENGTH];
|
||||
|
@ -509,7 +509,7 @@ uint8_t m_get_self_userstatus(const Messenger *m);
|
|||
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
||||
*
|
||||
* Arguments:
|
||||
* format - Avatar image format or NONE for user with no avatar (see AVATARFORMAT);
|
||||
* format - Avatar image format or NONE for user with no avatar (see AVATAR_FORMAT);
|
||||
* data - pointer to the avatar data (may be NULL it the format is NONE);
|
||||
* length - length of image data. Must be <= MAX_AVATAR_DATA_LENGTH.
|
||||
*
|
||||
|
@ -528,7 +528,7 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len
|
|||
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
||||
*
|
||||
* Arguments:
|
||||
* format - destination pointer to the avatar image format (see AVATARFORMAT);
|
||||
* format - destination pointer to the avatar image format (see AVATAR_FORMAT);
|
||||
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
||||
* length - destination pointer to the image data length;
|
||||
* maxlen - length of the destination buffer 'buf';
|
||||
|
@ -541,8 +541,23 @@ int m_set_avatar(Messenger *m, uint8_t format, const uint8_t *data, uint32_t len
|
|||
int m_get_self_avatar(const Messenger *m, uint8_t *format, uint8_t *buf, uint32_t *length, uint32_t maxlen,
|
||||
uint8_t *hash);
|
||||
|
||||
/* Generates a cryptographic hash of the given data.
|
||||
* This function may be used by clients for any purpose, but is provided primarily for
|
||||
* validating cached avatars.
|
||||
* This function is a wrapper to internal message-digest functions.
|
||||
*
|
||||
* Arguments:
|
||||
* hash - destination buffer for the hash data, it must be exactly crypto_hash_sha256_BYTES bytes long.
|
||||
* data - data to be hashed;
|
||||
* datalen - length of the data;
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure.
|
||||
*/
|
||||
int m_hash(uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
||||
|
||||
/* Generates a cryptographic hash of the given avatar data.
|
||||
* This function is a wrapper to internal message-digest functions and specifically provided
|
||||
* This function is a wrapper to m_hash and specifically provided
|
||||
* to generate hashes from user avatars that may be memcmp()ed with the values returned by the
|
||||
* other avatar functions. It is specially important to validate cached avatars.
|
||||
*
|
||||
|
@ -694,7 +709,7 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess
|
|||
* Function format is:
|
||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
|
||||
*
|
||||
* where 'format' is the avatar image format (see AVATARFORMAT) and 'hash' is the hash of
|
||||
* where 'format' is the avatar image format (see AVATAR_FORMAT) and 'hash' is the hash of
|
||||
* the avatar data for caching purposes and it is exactly AVATAR_HASH_LENGTH long. If the
|
||||
* image format is NONE, the hash is zeroed.
|
||||
*
|
||||
|
@ -710,7 +725,7 @@ void m_callback_avatar_info(Messenger *m, void (*function)(Messenger *m, int32_t
|
|||
* Function format is:
|
||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
||||
*
|
||||
* where 'format' is the avatar image format (see AVATARFORMAT); 'hash' is the
|
||||
* where 'format' is the avatar image format (see AVATAR_FORMAT); 'hash' is the
|
||||
* locally-calculated cryptographic hash of the avatar data and it is exactly
|
||||
* AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
|
||||
* of such data.
|
||||
|
|
|
@ -826,9 +826,9 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t
|
|||
return m_get_self_avatar(m, format, buf, length, maxlen, hash);
|
||||
}
|
||||
|
||||
int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||
int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen)
|
||||
{
|
||||
return m_avatar_hash(hash, data, datalen);
|
||||
return m_hash(hash, data, datalen);
|
||||
}
|
||||
|
||||
int tox_request_avatar_info(const Tox *tox, const int32_t friendnumber)
|
||||
|
|
|
@ -37,8 +37,8 @@ extern "C" {
|
|||
#define TOX_MAX_MESSAGE_LENGTH 1368
|
||||
#define TOX_MAX_STATUSMESSAGE_LENGTH 1007
|
||||
#define TOX_CLIENT_ID_SIZE 32
|
||||
#define TOX_MAX_AVATAR_DATA_LENGTH 16384
|
||||
#define TOX_AVATAR_HASH_LENGTH 32
|
||||
#define TOX_AVATAR_MAX_DATA_LENGTH 16384
|
||||
#define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32
|
||||
|
||||
#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t))
|
||||
|
||||
|
@ -73,14 +73,14 @@ typedef enum {
|
|||
TOX_USERSTATUS;
|
||||
|
||||
|
||||
/* AVATARFORMAT -
|
||||
/* AVATAR_FORMAT -
|
||||
* Data formats for user avatar images
|
||||
*/
|
||||
typedef enum {
|
||||
TOX_AVATARFORMAT_NONE,
|
||||
TOX_AVATARFORMAT_PNG
|
||||
TOX_AVATAR_FORMAT_NONE = 0,
|
||||
TOX_AVATAR_FORMAT_PNG
|
||||
}
|
||||
TOX_AVATARFORMAT;
|
||||
TOX_AVATAR_FORMAT;
|
||||
|
||||
#ifndef __TOX_DEFINED__
|
||||
#define __TOX_DEFINED__
|
||||
|
@ -538,7 +538,7 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
|
|||
* Function format is:
|
||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, void *userdata)
|
||||
*
|
||||
* where 'format' is the avatar image format (see TOX_AVATARFORMAT) and 'hash' is the hash of
|
||||
* where 'format' is the avatar image format (see TOX_AVATAR_FORMAT) and 'hash' is the hash of
|
||||
* the avatar data for caching purposes and it is exactly TOX_AVATAR_HASH_LENGTH long. If the
|
||||
* image format is NONE, the hash is zeroed.
|
||||
*
|
||||
|
@ -554,7 +554,7 @@ void tox_callback_avatar_info(Tox *tox, void (*function)(Tox *tox, int32_t, uint
|
|||
* Function format is:
|
||||
* function(Tox *tox, int32_t friendnumber, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t datalen, void *userdata)
|
||||
*
|
||||
* where 'format' is the avatar image format (see TOX_AVATARFORMAT); 'hash' is the
|
||||
* where 'format' is the avatar image format (see TOX_AVATAR_FORMAT); 'hash' is the
|
||||
* locally-calculated cryptographic hash of the avatar data and it is exactly
|
||||
* TOX_AVATAR_HASH_LENGTH long; 'data' is the avatar image data and 'datalen' is the length
|
||||
* of such data.
|
||||
|
@ -577,9 +577,9 @@ void tox_callback_avatar_data(Tox *tox, void (*function)(Tox *tox, int32_t, uint
|
|||
* Notice that the library treats the image as raw data and does not interpret it by any way.
|
||||
*
|
||||
* Arguments:
|
||||
* format - Avatar image format or NONE for user with no avatar (see TOX_AVATARFORMAT);
|
||||
* format - Avatar image format or NONE for user with no avatar (see TOX_AVATAR_FORMAT);
|
||||
* data - pointer to the avatar data (may be NULL it the format is NONE);
|
||||
* length - length of image data. Must be <= TOX_MAX_AVATAR_DATA_LENGTH.
|
||||
* length - length of image data. Must be <= TOX_AVATAR_MAX_DATA_LENGTH.
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure.
|
||||
|
@ -597,7 +597,7 @@ int tox_set_avatar(Tox *tox, uint8_t format, const uint8_t *data, uint32_t lengt
|
|||
* If any of the pointers format, buf, length, and hash are NULL, that particular field will be ignored.
|
||||
*
|
||||
* Arguments:
|
||||
* format - destination pointer to the avatar image format (see TOX_AVATARFORMAT);
|
||||
* format - destination pointer to the avatar image format (see TOX_AVATAR_FORMAT);
|
||||
* buf - destination buffer to the image data. Must have at least 'maxlen' bytes;
|
||||
* length - destination pointer to the image data length;
|
||||
* maxlen - length of the destination buffer 'buf';
|
||||
|
@ -611,21 +611,21 @@ int tox_get_self_avatar(const Tox *tox, uint8_t *format, uint8_t *buf, uint32_t
|
|||
uint8_t *hash);
|
||||
|
||||
|
||||
/* Generates a cryptographic hash of the given avatar data.
|
||||
* This function is a wrapper to internal message-digest functions and specifically provided
|
||||
* to generate hashes from user avatars that may be memcmp()ed with the values returned by the
|
||||
* other avatar functions. It is specially important to validate cached avatars.
|
||||
/* Generates a cryptographic hash of the given data.
|
||||
* This function may be used by clients for any purpose, but is provided primarily for
|
||||
* validating cached avatars. This use is highly recommended to avoid unnecessary avatar
|
||||
* updates.
|
||||
* This function is a wrapper to internal message-digest functions.
|
||||
*
|
||||
* Arguments:
|
||||
* hash - destination buffer for the hash data, it must be exactly TOX_AVATAR_HASH_LENGTH bytes long.
|
||||
* data - avatar image data;
|
||||
* datalen - length of the avatar image data; it must be <= TOX_MAX_AVATAR_DATA_LENGTH.
|
||||
* hash - destination buffer for the hash data, it must be exactly TOX_HASH_LENGTH bytes long.
|
||||
* data - data to be hashed;
|
||||
* datalen - length of the data; for avatars, should be TOX_AVATAR_MAX_DATA_LENGTH
|
||||
*
|
||||
* returns 0 on success
|
||||
* returns -1 on failure.
|
||||
*/
|
||||
int tox_avatar_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
||||
|
||||
int tox_hash(const Tox *tox, uint8_t *hash, const uint8_t *data, const uint32_t datalen);
|
||||
|
||||
/* Request avatar information from a friend.
|
||||
* Asks a friend to provide their avatar information (image format and hash). The friend may
|
||||
|
|
Loading…
Reference in New Issue
Block a user