diff options
Diffstat (limited to 'core/Messenger.c')
-rw-r--r-- | core/Messenger.c | 518 |
1 files changed, 248 insertions, 270 deletions
diff --git a/core/Messenger.c b/core/Messenger.c index d26bba56..a6189941 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -24,40 +24,8 @@ | |||
24 | #include "Messenger.h" | 24 | #include "Messenger.h" |
25 | #define MIN(a,b) (((a)<(b))?(a):(b)) | 25 | #define MIN(a,b) (((a)<(b))?(a):(b)) |
26 | 26 | ||
27 | typedef struct { | 27 | static void set_friend_status(Messenger *m, int friendnumber, uint8_t status); |
28 | uint8_t client_id[CLIENT_ID_SIZE]; | 28 | static int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); |
29 | int crypt_connection_id; | ||
30 | uint64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */ | ||
31 | uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */ | ||
32 | uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */ | ||
33 | uint8_t name[MAX_NAME_LENGTH]; | ||
34 | uint8_t name_sent; /* 0 if we didn't send our name to this friend 1 if we have. */ | ||
35 | uint8_t *statusmessage; | ||
36 | uint16_t statusmessage_length; | ||
37 | uint8_t statusmessage_sent; | ||
38 | USERSTATUS userstatus; | ||
39 | uint8_t userstatus_sent; | ||
40 | uint16_t info_size; /* length of the info */ | ||
41 | uint32_t message_id; /* a semi-unique id used in read receipts */ | ||
42 | uint8_t receives_read_receipts; /* shall we send read receipts to this person? */ | ||
43 | } Friend; | ||
44 | |||
45 | uint8_t self_public_key[crypto_box_PUBLICKEYBYTES]; | ||
46 | |||
47 | static uint8_t self_name[MAX_NAME_LENGTH]; | ||
48 | static uint16_t self_name_length; | ||
49 | |||
50 | static uint8_t self_statusmessage[MAX_STATUSMESSAGE_LENGTH]; | ||
51 | static uint16_t self_statusmessage_length; | ||
52 | |||
53 | static USERSTATUS self_userstatus; | ||
54 | |||
55 | static Friend *friendlist; | ||
56 | static uint32_t numfriends; | ||
57 | |||
58 | |||
59 | static void set_friend_status(int friendnumber, uint8_t status); | ||
60 | static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length); | ||
61 | 29 | ||
62 | /* 1 if we are online | 30 | /* 1 if we are online |
63 | 0 if we are offline | 31 | 0 if we are offline |
@@ -65,24 +33,24 @@ static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *da | |||
65 | 33 | ||
66 | /* set the size of the friend list to numfriends | 34 | /* set the size of the friend list to numfriends |
67 | return -1 if realloc fails */ | 35 | return -1 if realloc fails */ |
68 | int realloc_friendlist(uint32_t num) { | 36 | int realloc_friendlist(Messenger *m, uint32_t num) { |
69 | Friend *newfriendlist = realloc(friendlist, num*sizeof(Friend)); | 37 | Friend *newfriendlist = realloc(m->friendlist, num*sizeof(Friend)); |
70 | if (newfriendlist == NULL) | 38 | if (newfriendlist == NULL) |
71 | return -1; | 39 | return -1; |
72 | memset(&newfriendlist[num-1], 0, sizeof(Friend)); | 40 | memset(&newfriendlist[num-1], 0, sizeof(Friend)); |
73 | friendlist = newfriendlist; | 41 | m->friendlist = newfriendlist; |
74 | return 0; | 42 | return 0; |
75 | } | 43 | } |
76 | 44 | ||
77 | /* return the friend id associated to that public key. | 45 | /* return the friend id associated to that public key. |
78 | return -1 if no such friend */ | 46 | return -1 if no such friend */ |
79 | int getfriend_id(uint8_t *client_id) | 47 | int getfriend_id(Messenger *m, uint8_t *client_id) |
80 | { | 48 | { |
81 | uint32_t i; | 49 | uint32_t i; |
82 | 50 | ||
83 | for (i = 0; i < numfriends; ++i) { | 51 | for (i = 0; i < m->numfriends; ++i) { |
84 | if (friendlist[i].status > 0) | 52 | if (m->friendlist[i].status > 0) |
85 | if (memcmp(client_id, friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) | 53 | if (memcmp(client_id, m->friendlist[i].client_id, crypto_box_PUBLICKEYBYTES) == 0) |
86 | return i; | 54 | return i; |
87 | } | 55 | } |
88 | 56 | ||
@@ -93,13 +61,13 @@ int getfriend_id(uint8_t *client_id) | |||
93 | make sure that client_id is of size CLIENT_ID_SIZE. | 61 | make sure that client_id is of size CLIENT_ID_SIZE. |
94 | return 0 if success | 62 | return 0 if success |
95 | return -1 if failure. */ | 63 | return -1 if failure. */ |
96 | int getclient_id(int friend_id, uint8_t *client_id) | 64 | int getclient_id(Messenger *m, int friend_id, uint8_t *client_id) |
97 | { | 65 | { |
98 | if (friend_id >= numfriends || friend_id < 0) | 66 | if (friend_id >= m->numfriends || friend_id < 0) |
99 | return -1; | 67 | return -1; |
100 | 68 | ||
101 | if (friendlist[friend_id].status > 0) { | 69 | if (m->friendlist[friend_id].status > 0) { |
102 | memcpy(client_id, friendlist[friend_id].client_id, CLIENT_ID_SIZE); | 70 | memcpy(client_id, m->friendlist[friend_id].client_id, CLIENT_ID_SIZE); |
103 | return 0; | 71 | return 0; |
104 | } | 72 | } |
105 | 73 | ||
@@ -118,7 +86,7 @@ int getclient_id(int friend_id, uint8_t *client_id) | |||
118 | * return FAERR_ALREADYSENT if friend request already sent or already a friend | 86 | * return FAERR_ALREADYSENT if friend request already sent or already a friend |
119 | * return FAERR_UNKNOWN for unknown error | 87 | * return FAERR_UNKNOWN for unknown error |
120 | */ | 88 | */ |
121 | int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | 89 | int m_addfriend(Messenger *m, uint8_t *client_id, uint8_t *data, uint16_t length) |
122 | { | 90 | { |
123 | if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES | 91 | if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES |
124 | - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES | 92 | - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES |
@@ -128,57 +96,57 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length) | |||
128 | return FAERR_NOMESSAGE; | 96 | return FAERR_NOMESSAGE; |
129 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) | 97 | if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) |
130 | return FAERR_OWNKEY; | 98 | return FAERR_OWNKEY; |
131 | if (getfriend_id(client_id) != -1) | 99 | if (getfriend_id(m, client_id) != -1) |
132 | return FAERR_ALREADYSENT; | 100 | return FAERR_ALREADYSENT; |
133 | 101 | ||
134 | /* resize the friend list if necessary */ | 102 | /* resize the friend list if necessary */ |
135 | realloc_friendlist(numfriends + 1); | 103 | realloc_friendlist(m, m->numfriends + 1); |
136 | 104 | ||
137 | uint32_t i; | 105 | uint32_t i; |
138 | for (i = 0; i <= numfriends; ++i) { | 106 | for (i = 0; i <= m->numfriends; ++i) { |
139 | if (friendlist[i].status == NOFRIEND) { | 107 | if (m->friendlist[i].status == NOFRIEND) { |
140 | DHT_addfriend(client_id); | 108 | DHT_addfriend(client_id); |
141 | friendlist[i].status = FRIEND_ADDED; | 109 | m->friendlist[i].status = FRIEND_ADDED; |
142 | friendlist[i].crypt_connection_id = -1; | 110 | m->friendlist[i].crypt_connection_id = -1; |
143 | friendlist[i].friend_request_id = -1; | 111 | m->friendlist[i].friend_request_id = -1; |
144 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 112 | memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
145 | friendlist[i].statusmessage = calloc(1, 1); | 113 | m->friendlist[i].statusmessage = calloc(1, 1); |
146 | friendlist[i].statusmessage_length = 1; | 114 | m->friendlist[i].statusmessage_length = 1; |
147 | friendlist[i].userstatus = USERSTATUS_NONE; | 115 | m->friendlist[i].userstatus = USERSTATUS_NONE; |
148 | memcpy(friendlist[i].info, data, length); | 116 | memcpy(m->friendlist[i].info, data, length); |
149 | friendlist[i].info_size = length; | 117 | m->friendlist[i].info_size = length; |
150 | friendlist[i].message_id = 0; | 118 | m->friendlist[i].message_id = 0; |
151 | friendlist[i].receives_read_receipts = 1; /* default: YES */ | 119 | m->friendlist[i].receives_read_receipts = 1; /* default: YES */ |
152 | 120 | ||
153 | ++numfriends; | 121 | ++ m->numfriends; |
154 | return i; | 122 | return i; |
155 | } | 123 | } |
156 | } | 124 | } |
157 | return FAERR_UNKNOWN; | 125 | return FAERR_UNKNOWN; |
158 | } | 126 | } |
159 | 127 | ||
160 | int m_addfriend_norequest(uint8_t * client_id) | 128 | int m_addfriend_norequest(Messenger *m, uint8_t * client_id) |
161 | { | 129 | { |
162 | if (getfriend_id(client_id) != -1) | 130 | if (getfriend_id(m, client_id) != -1) |
163 | return -1; | 131 | return -1; |
164 | 132 | ||
165 | /* resize the friend list if necessary */ | 133 | /* resize the friend list if necessary */ |
166 | realloc_friendlist(numfriends + 1); | 134 | realloc_friendlist(m, m->numfriends + 1); |
167 | 135 | ||
168 | uint32_t i; | 136 | uint32_t i; |
169 | for (i = 0; i <= numfriends; ++i) { | 137 | for (i = 0; i <= m->numfriends; ++i) { |
170 | if(friendlist[i].status == NOFRIEND) { | 138 | if(m->friendlist[i].status == NOFRIEND) { |
171 | DHT_addfriend(client_id); | 139 | DHT_addfriend(client_id); |
172 | set_friend_status(i, FRIEND_REQUESTED); | 140 | m->friendlist[i].status = FRIEND_REQUESTED; |
173 | friendlist[i].crypt_connection_id = -1; | 141 | m->friendlist[i].crypt_connection_id = -1; |
174 | friendlist[i].friend_request_id = -1; | 142 | m->friendlist[i].friend_request_id = -1; |
175 | memcpy(friendlist[i].client_id, client_id, CLIENT_ID_SIZE); | 143 | memcpy(m->friendlist[i].client_id, client_id, CLIENT_ID_SIZE); |
176 | friendlist[i].statusmessage = calloc(1, 1); | 144 | m->friendlist[i].statusmessage = calloc(1, 1); |
177 | friendlist[i].statusmessage_length = 1; | 145 | m->friendlist[i].statusmessage_length = 1; |
178 | friendlist[i].userstatus = USERSTATUS_NONE; | 146 | m->friendlist[i].userstatus = USERSTATUS_NONE; |
179 | friendlist[i].message_id = 0; | 147 | m->friendlist[i].message_id = 0; |
180 | friendlist[i].receives_read_receipts = 1; /* default: YES */ | 148 | m->friendlist[i].receives_read_receipts = 1; /* default: YES */ |
181 | ++numfriends; | 149 | ++ m->numfriends; |
182 | return i; | 150 | return i; |
183 | } | 151 | } |
184 | } | 152 | } |
@@ -188,23 +156,23 @@ int m_addfriend_norequest(uint8_t * client_id) | |||
188 | /* remove a friend | 156 | /* remove a friend |
189 | return 0 if success | 157 | return 0 if success |
190 | return -1 if failure */ | 158 | return -1 if failure */ |
191 | int m_delfriend(int friendnumber) | 159 | int m_delfriend(Messenger *m, int friendnumber) |
192 | { | 160 | { |
193 | if (friendnumber >= numfriends || friendnumber < 0) | 161 | if (friendnumber >= m->numfriends || friendnumber < 0) |
194 | return -1; | 162 | return -1; |
195 | 163 | ||
196 | DHT_delfriend(friendlist[friendnumber].client_id); | 164 | DHT_delfriend(m->friendlist[friendnumber].client_id); |
197 | crypto_kill(friendlist[friendnumber].crypt_connection_id); | 165 | crypto_kill(m->friendlist[friendnumber].crypt_connection_id); |
198 | free(friendlist[friendnumber].statusmessage); | 166 | free(m->friendlist[friendnumber].statusmessage); |
199 | memset(&friendlist[friendnumber], 0, sizeof(Friend)); | 167 | memset(&(m->friendlist[friendnumber]), 0, sizeof(Friend)); |
200 | uint32_t i; | 168 | uint32_t i; |
201 | 169 | ||
202 | for (i = numfriends; i != 0; --i) { | 170 | for (i = m->numfriends; i != 0; --i) { |
203 | if (friendlist[i-1].status != NOFRIEND) | 171 | if (m->friendlist[i-1].status != NOFRIEND) |
204 | break; | 172 | break; |
205 | } | 173 | } |
206 | numfriends = i; | 174 | m->numfriends = i; |
207 | realloc_friendlist(numfriends + 1); | 175 | realloc_friendlist(m, m->numfriends + 1); |
208 | 176 | ||
209 | return 0; | 177 | return 0; |
210 | } | 178 | } |
@@ -214,31 +182,31 @@ int m_delfriend(int friendnumber) | |||
214 | return FRIEND_REQUESTED if the friend request was sent | 182 | return FRIEND_REQUESTED if the friend request was sent |
215 | return FRIEND_ADDED if the friend was added | 183 | return FRIEND_ADDED if the friend was added |
216 | return NOFRIEND if there is no friend with that number */ | 184 | return NOFRIEND if there is no friend with that number */ |
217 | int m_friendstatus(int friendnumber) | 185 | int m_friendstatus(Messenger *m, int friendnumber) |
218 | { | 186 | { |
219 | if (friendnumber < 0 || friendnumber >= numfriends) | 187 | if (friendnumber < 0 || friendnumber >= m->numfriends) |
220 | return NOFRIEND; | 188 | return NOFRIEND; |
221 | return friendlist[friendnumber].status; | 189 | return m->friendlist[friendnumber].status; |
222 | } | 190 | } |
223 | 191 | ||
224 | /* send a text chat message to an online friend | 192 | /* send a text chat message to an online friend |
225 | return the message id if packet was successfully put into the send queue | 193 | return the message id if packet was successfully put into the send queue |
226 | return 0 if it was not */ | 194 | return 0 if it was not */ |
227 | uint32_t m_sendmessage(int friendnumber, uint8_t *message, uint32_t length) | 195 | uint32_t m_sendmessage(Messenger *m, int friendnumber, uint8_t *message, uint32_t length) |
228 | { | 196 | { |
229 | if (friendnumber < 0 || friendnumber >= numfriends) | 197 | if (friendnumber < 0 || friendnumber >= m->numfriends) |
230 | return 0; | 198 | return 0; |
231 | uint32_t msgid = ++friendlist[friendnumber].message_id; | 199 | uint32_t msgid = ++m->friendlist[friendnumber].message_id; |
232 | if (msgid == 0) | 200 | if (msgid == 0) |
233 | msgid = 1; /* otherwise, false error */ | 201 | msgid = 1; /* otherwise, false error */ |
234 | if(m_sendmessage_withid(friendnumber, msgid, message, length)) { | 202 | if(m_sendmessage_withid(m, friendnumber, msgid, message, length)) { |
235 | return msgid; | 203 | return msgid; |
236 | } | 204 | } |
237 | 205 | ||
238 | return 0; | 206 | return 0; |
239 | } | 207 | } |
240 | 208 | ||
241 | uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) | 209 | uint32_t m_sendmessage_withid(Messenger *m, int friendnumber, uint32_t theid, uint8_t *message, uint32_t length) |
242 | { | 210 | { |
243 | if (length >= (MAX_DATA_SIZE - sizeof(theid))) | 211 | if (length >= (MAX_DATA_SIZE - sizeof(theid))) |
244 | return 0; | 212 | return 0; |
@@ -246,34 +214,34 @@ uint32_t m_sendmessage_withid(int friendnumber, uint32_t theid, uint8_t *message | |||
246 | theid = htonl(theid); | 214 | theid = htonl(theid); |
247 | memcpy(temp, &theid, sizeof(theid)); | 215 | memcpy(temp, &theid, sizeof(theid)); |
248 | memcpy(temp + sizeof(theid), message, length); | 216 | memcpy(temp + sizeof(theid), message, length); |
249 | return write_cryptpacket_id(friendnumber, PACKET_ID_MESSAGE, temp, length + sizeof(theid)); | 217 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_MESSAGE, temp, length + sizeof(theid)); |
250 | } | 218 | } |
251 | 219 | ||
252 | /* send an action to an online friend | 220 | /* send an action to an online friend |
253 | return 1 if packet was successfully put into the send queue | 221 | return 1 if packet was successfully put into the send queue |
254 | return 0 if it was not */ | 222 | return 0 if it was not */ |
255 | int m_sendaction(int friendnumber, uint8_t *action, uint32_t length) | 223 | int m_sendaction(Messenger *m, int friendnumber, uint8_t *action, uint32_t length) |
256 | { | 224 | { |
257 | return write_cryptpacket_id(friendnumber, PACKET_ID_ACTION, action, length); | 225 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_ACTION, action, length); |
258 | } | 226 | } |
259 | 227 | ||
260 | /* send a name packet to friendnumber | 228 | /* send a name packet to friendnumber |
261 | length is the length with the NULL terminator*/ | 229 | length is the length with the NULL terminator*/ |
262 | static int m_sendname(int friendnumber, uint8_t * name, uint16_t length) | 230 | static int m_sendname(Messenger *m, int friendnumber, uint8_t * name, uint16_t length) |
263 | { | 231 | { |
264 | if(length > MAX_NAME_LENGTH || length == 0) | 232 | if(length > MAX_NAME_LENGTH || length == 0) |
265 | return 0; | 233 | return 0; |
266 | return write_cryptpacket_id(friendnumber, PACKET_ID_NICKNAME, name, length); | 234 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_NICKNAME, name, length); |
267 | } | 235 | } |
268 | 236 | ||
269 | /* set the name of a friend | 237 | /* set the name of a friend |
270 | return 0 if success | 238 | return 0 if success |
271 | return -1 if failure */ | 239 | return -1 if failure */ |
272 | static int setfriendname(int friendnumber, uint8_t * name) | 240 | static int setfriendname(Messenger *m, int friendnumber, uint8_t * name) |
273 | { | 241 | { |
274 | if (friendnumber >= numfriends || friendnumber < 0) | 242 | if (friendnumber >= m->numfriends || friendnumber < 0) |
275 | return -1; | 243 | return -1; |
276 | memcpy(friendlist[friendnumber].name, name, MAX_NAME_LENGTH); | 244 | memcpy(m->friendlist[friendnumber].name, name, MAX_NAME_LENGTH); |
277 | return 0; | 245 | return 0; |
278 | } | 246 | } |
279 | 247 | ||
@@ -283,15 +251,15 @@ static int setfriendname(int friendnumber, uint8_t * name) | |||
283 | length is the length of name with the NULL terminator | 251 | length is the length of name with the NULL terminator |
284 | return 0 if success | 252 | return 0 if success |
285 | return -1 if failure */ | 253 | return -1 if failure */ |
286 | int setname(uint8_t * name, uint16_t length) | 254 | int setname(Messenger *m, uint8_t * name, uint16_t length) |
287 | { | 255 | { |
288 | if (length > MAX_NAME_LENGTH || length == 0) | 256 | if (length > MAX_NAME_LENGTH || length == 0) |
289 | return -1; | 257 | return -1; |
290 | memcpy(self_name, name, length); | 258 | memcpy(m->name, name, length); |
291 | self_name_length = length; | 259 | m->name_length = length; |
292 | uint32_t i; | 260 | uint32_t i; |
293 | for (i = 0; i < numfriends; ++i) | 261 | for (i = 0; i < m->numfriends; ++i) |
294 | friendlist[i].name_sent = 0; | 262 | m->friendlist[i].name_sent = 0; |
295 | return 0; | 263 | return 0; |
296 | } | 264 | } |
297 | 265 | ||
@@ -299,10 +267,10 @@ int setname(uint8_t * name, uint16_t length) | |||
299 | put it in name | 267 | put it in name |
300 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. | 268 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. |
301 | return the length of the name */ | 269 | return the length of the name */ |
302 | uint16_t getself_name(uint8_t *name) | 270 | uint16_t getself_name(Messenger *m, uint8_t *name) |
303 | { | 271 | { |
304 | memcpy(name, self_name, self_name_length); | 272 | memcpy(name, m->name, m->name_length); |
305 | return self_name_length; | 273 | return m->name_length; |
306 | } | 274 | } |
307 | 275 | ||
308 | /* get name of friendnumber | 276 | /* get name of friendnumber |
@@ -310,279 +278,288 @@ uint16_t getself_name(uint8_t *name) | |||
310 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. | 278 | name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH bytes. |
311 | return 0 if success | 279 | return 0 if success |
312 | return -1 if failure */ | 280 | return -1 if failure */ |
313 | int getname(int friendnumber, uint8_t * name) | 281 | int getname(Messenger *m, int friendnumber, uint8_t * name) |
314 | { | 282 | { |
315 | if (friendnumber >= numfriends || friendnumber < 0) | 283 | if (friendnumber >= m->numfriends || friendnumber < 0) |
316 | return -1; | 284 | return -1; |
317 | memcpy(name, friendlist[friendnumber].name, MAX_NAME_LENGTH); | 285 | memcpy(name, m->friendlist[friendnumber].name, MAX_NAME_LENGTH); |
318 | return 0; | 286 | return 0; |
319 | } | 287 | } |
320 | 288 | ||
321 | int m_set_statusmessage(uint8_t *status, uint16_t length) | 289 | int m_set_statusmessage(Messenger *m, uint8_t *status, uint16_t length) |
322 | { | 290 | { |
323 | if (length > MAX_STATUSMESSAGE_LENGTH) | 291 | if (length > MAX_STATUSMESSAGE_LENGTH) |
324 | return -1; | 292 | return -1; |
325 | memcpy(self_statusmessage, status, length); | 293 | memcpy(m->statusmessage, status, length); |
326 | self_statusmessage_length = length; | 294 | m->statusmessage_length = length; |
327 | 295 | ||
328 | uint32_t i; | 296 | uint32_t i; |
329 | for (i = 0; i < numfriends; ++i) | 297 | for (i = 0; i < m->numfriends; ++i) |
330 | friendlist[i].statusmessage_sent = 0; | 298 | m->friendlist[i].statusmessage_sent = 0; |
331 | return 0; | 299 | return 0; |
332 | } | 300 | } |
333 | 301 | ||
334 | int m_set_userstatus(USERSTATUS status) | 302 | int m_set_userstatus(Messenger *m, USERSTATUS status) |
335 | { | 303 | { |
336 | if (status >= USERSTATUS_INVALID) { | 304 | if (status >= USERSTATUS_INVALID) { |
337 | return -1; | 305 | return -1; |
338 | } | 306 | } |
339 | self_userstatus = status; | 307 | m->userstatus = status; |
340 | uint32_t i; | 308 | uint32_t i; |
341 | for (i = 0; i < numfriends; ++i) | 309 | for (i = 0; i < m->numfriends; ++i) |
342 | friendlist[i].userstatus_sent = 0; | 310 | m->friendlist[i].userstatus_sent = 0; |
343 | return 0; | 311 | return 0; |
344 | } | 312 | } |
345 | 313 | ||
346 | /* return the size of friendnumber's user status | 314 | /* return the size of friendnumber's user status |
347 | guaranteed to be at most MAX_STATUSMESSAGE_LENGTH */ | 315 | guaranteed to be at most MAX_STATUSMESSAGE_LENGTH */ |
348 | int m_get_statusmessage_size(int friendnumber) | 316 | int m_get_statusmessage_size(Messenger *m, int friendnumber) |
349 | { | 317 | { |
350 | if (friendnumber >= numfriends || friendnumber < 0) | 318 | if (friendnumber >= m->numfriends || friendnumber < 0) |
351 | return -1; | 319 | return -1; |
352 | return friendlist[friendnumber].statusmessage_length; | 320 | return m->friendlist[friendnumber].statusmessage_length; |
353 | } | 321 | } |
354 | 322 | ||
355 | /* copy the user status of friendnumber into buf, truncating if needed to maxlen | 323 | /* copy the user status of friendnumber into buf, truncating if needed to maxlen |
356 | bytes, use m_get_statusmessage_size to find out how much you need to allocate */ | 324 | bytes, use m_get_statusmessage_size to find out how much you need to allocate */ |
357 | int m_copy_statusmessage(int friendnumber, uint8_t * buf, uint32_t maxlen) | 325 | int m_copy_statusmessage(Messenger *m, int friendnumber, uint8_t * buf, uint32_t maxlen) |
358 | { | 326 | { |
359 | if (friendnumber >= numfriends || friendnumber < 0) | 327 | if (friendnumber >= m->numfriends || friendnumber < 0) |
360 | return -1; | 328 | return -1; |
361 | memset(buf, 0, maxlen); | 329 | memset(buf, 0, maxlen); |
362 | memcpy(buf, friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); | 330 | memcpy(buf, m->friendlist[friendnumber].statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); |
363 | return 0; | 331 | return 0; |
364 | } | 332 | } |
365 | 333 | ||
366 | int m_copy_self_statusmessage(uint8_t * buf, uint32_t maxlen) | 334 | int m_copy_self_statusmessage(Messenger *m, uint8_t * buf, uint32_t maxlen) |
367 | { | 335 | { |
368 | memset(buf, 0, maxlen); | 336 | memset(buf, 0, maxlen); |
369 | memcpy(buf, self_statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); | 337 | memcpy(buf, m->statusmessage, MIN(maxlen, MAX_STATUSMESSAGE_LENGTH) - 1); |
370 | return 0; | 338 | return 0; |
371 | } | 339 | } |
372 | 340 | ||
373 | USERSTATUS m_get_userstatus(int friendnumber) | 341 | USERSTATUS m_get_userstatus(Messenger *m, int friendnumber) |
374 | { | 342 | { |
375 | if (friendnumber >= numfriends || friendnumber < 0) | 343 | if (friendnumber >= m->numfriends || friendnumber < 0) |
376 | return USERSTATUS_INVALID; | 344 | return USERSTATUS_INVALID; |
377 | USERSTATUS status = friendlist[friendnumber].userstatus; | 345 | USERSTATUS status = m->friendlist[friendnumber].userstatus; |
378 | if (status >= USERSTATUS_INVALID) { | 346 | if (status >= USERSTATUS_INVALID) { |
379 | status = USERSTATUS_NONE; | 347 | status = USERSTATUS_NONE; |
380 | } | 348 | } |
381 | return status; | 349 | return status; |
382 | } | 350 | } |
383 | 351 | ||
384 | USERSTATUS m_get_self_userstatus(void) | 352 | USERSTATUS m_get_self_userstatus(Messenger *m) |
385 | { | 353 | { |
386 | return self_userstatus; | 354 | return m->userstatus; |
387 | } | 355 | } |
388 | 356 | ||
389 | static int send_statusmessage(int friendnumber, uint8_t * status, uint16_t length) | 357 | static int send_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) |
390 | { | 358 | { |
391 | return write_cryptpacket_id(friendnumber, PACKET_ID_STATUSMESSAGE, status, length); | 359 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_STATUSMESSAGE, status, length); |
392 | } | 360 | } |
393 | 361 | ||
394 | static int send_userstatus(int friendnumber, USERSTATUS status) | 362 | static int send_userstatus(Messenger *m, int friendnumber, USERSTATUS status) |
395 | { | 363 | { |
396 | uint8_t stat = status; | 364 | uint8_t stat = status; |
397 | return write_cryptpacket_id(friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); | 365 | return write_cryptpacket_id(m, friendnumber, PACKET_ID_USERSTATUS, &stat, sizeof(stat)); |
398 | } | 366 | } |
399 | 367 | ||
400 | static int set_friend_statusmessage(int friendnumber, uint8_t * status, uint16_t length) | 368 | static int set_friend_statusmessage(Messenger *m, int friendnumber, uint8_t * status, uint16_t length) |
401 | { | 369 | { |
402 | if (friendnumber >= numfriends || friendnumber < 0) | 370 | if (friendnumber >= m->numfriends || friendnumber < 0) |
403 | return -1; | 371 | return -1; |
404 | uint8_t *newstatus = calloc(length, 1); | 372 | uint8_t *newstatus = calloc(length, 1); |
405 | memcpy(newstatus, status, length); | 373 | memcpy(newstatus, status, length); |
406 | free(friendlist[friendnumber].statusmessage); | 374 | free(m->friendlist[friendnumber].statusmessage); |
407 | friendlist[friendnumber].statusmessage = newstatus; | 375 | m->friendlist[friendnumber].statusmessage = newstatus; |
408 | friendlist[friendnumber].statusmessage_length = length; | 376 | m->friendlist[friendnumber].statusmessage_length = length; |
409 | return 0; | 377 | return 0; |
410 | } | 378 | } |
411 | 379 | ||
412 | static void set_friend_userstatus(int friendnumber, USERSTATUS status) | 380 | static void set_friend_userstatus(Messenger *m, int friendnumber, USERSTATUS status) |
413 | { | 381 | { |
414 | friendlist[friendnumber].userstatus = status; | 382 | m->friendlist[friendnumber].userstatus = status; |
415 | } | 383 | } |
416 | 384 | ||
417 | /* Sets whether we send read receipts for friendnumber. */ | 385 | /* Sets whether we send read receipts for friendnumber. */ |
418 | void m_set_sends_receipts(int friendnumber, int yesno) | 386 | void m_set_sends_receipts(Messenger *m, int friendnumber, int yesno) |
419 | { | 387 | { |
420 | if (yesno != 0 || yesno != 1) | 388 | if (yesno != 0 || yesno != 1) |
421 | return; | 389 | return; |
422 | if (friendnumber >= numfriends || friendnumber < 0) | 390 | if (friendnumber >= m->numfriends || friendnumber < 0) |
423 | return; | 391 | return; |
424 | friendlist[friendnumber].receives_read_receipts = yesno; | 392 | m->friendlist[friendnumber].receives_read_receipts = yesno; |
425 | } | 393 | } |
426 | 394 | ||
427 | /* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); | 395 | /* static void (*friend_request)(uint8_t *, uint8_t *, uint16_t); |
428 | static uint8_t friend_request_isset = 0; */ | 396 | static uint8_t friend_request_isset = 0; */ |
429 | /* set the function that will be executed when a friend request is received. */ | 397 | /* set the function that will be executed when a friend request is received. */ |
430 | void m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) | 398 | void m_callback_friendrequest(Messenger *m, void (*function)(uint8_t *, uint8_t *, uint16_t)) |
431 | { | 399 | { |
432 | callback_friendrequest(function); | 400 | callback_friendrequest(function); |
433 | } | 401 | } |
434 | 402 | ||
435 | static void (*friend_message)(int, uint8_t *, uint16_t); | ||
436 | static uint8_t friend_message_isset = 0; | ||
437 | |||
438 | /* set the function that will be executed when a message from a friend is received. */ | 403 | /* set the function that will be executed when a message from a friend is received. */ |
439 | void m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) | 404 | void m_callback_friendmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t)) |
440 | { | 405 | { |
441 | friend_message = function; | 406 | m->friend_message = function; |
442 | friend_message_isset = 1; | 407 | m->friend_message_isset = 1; |
443 | } | 408 | } |
444 | 409 | ||
445 | static void (*friend_action)(int, uint8_t *, uint16_t); | 410 | void m_callback_action(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t)) |
446 | static uint8_t friend_action_isset = 0; | ||
447 | void m_callback_action(void (*function)(int, uint8_t *, uint16_t)) | ||
448 | { | 411 | { |
449 | friend_action = function; | 412 | m->friend_action = function; |
450 | friend_action_isset = 1; | 413 | m->friend_action_isset = 1; |
451 | } | 414 | } |
452 | 415 | ||
453 | static void (*friend_namechange)(int, uint8_t *, uint16_t); | 416 | void m_callback_namechange(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t)) |
454 | static uint8_t friend_namechange_isset = 0; | ||
455 | void m_callback_namechange(void (*function)(int, uint8_t *, uint16_t)) | ||
456 | { | 417 | { |
457 | friend_namechange = function; | 418 | m->friend_namechange = function; |
458 | friend_namechange_isset = 1; | 419 | m->friend_namechange_isset = 1; |
459 | } | 420 | } |
460 | 421 | ||
461 | static void (*friend_statusmessagechange)(int, uint8_t *, uint16_t); | 422 | void m_callback_statusmessage(Messenger *m, void (*function)(Messenger *m, int, uint8_t *, uint16_t)) |
462 | static uint8_t friend_statusmessagechange_isset = 0; | ||
463 | void m_callback_statusmessage(void (*function)(int, uint8_t *, uint16_t)) | ||
464 | { | 423 | { |
465 | friend_statusmessagechange = function; | 424 | m->friend_statusmessagechange = function; |
466 | friend_statusmessagechange_isset = 1; | 425 | m->friend_statusmessagechange_isset = 1; |
467 | } | 426 | } |
468 | 427 | ||
469 | static void (*friend_userstatuschange)(int, USERSTATUS); | 428 | void m_callback_userstatus(Messenger *m, void (*function)(Messenger *m, int, USERSTATUS)) |
470 | static uint8_t friend_userstatuschange_isset = 0; | ||
471 | void m_callback_userstatus(void (*function)(int, USERSTATUS)) | ||
472 | { | 429 | { |
473 | friend_userstatuschange = function; | 430 | m->friend_userstatuschange = function; |
474 | friend_userstatuschange_isset = 1; | 431 | m->friend_userstatuschange_isset = 1; |
475 | } | 432 | } |
476 | 433 | ||
477 | static void (*read_receipt)(int, uint32_t); | 434 | void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, int, uint32_t)) |
478 | static uint8_t read_receipt_isset = 0; | ||
479 | void m_callback_read_receipt(void (*function)(int, uint32_t)) | ||
480 | { | 435 | { |
481 | read_receipt = function; | 436 | m->read_receipt = function; |
482 | read_receipt_isset = 1; | 437 | m->read_receipt_isset = 1; |
483 | } | 438 | } |
484 | 439 | ||
485 | static void (*friend_statuschange)(int, uint8_t); | 440 | void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, int, uint8_t)) |
486 | static uint8_t friend_statuschange_isset = 0; | ||
487 | void m_callback_friendstatus(void (*function)(int, uint8_t)) | ||
488 | { | 441 | { |
489 | friend_statuschange = function; | 442 | m->friend_connectionstatuschange = function; |
490 | friend_statuschange_isset = 1; | 443 | m->friend_connectionstatuschange_isset = 1; |
491 | } | 444 | } |
492 | 445 | ||
493 | static void set_friend_status(int friendnumber, uint8_t status) | 446 | static void check_friend_connectionstatus(Messenger *m, int friendnumber, uint8_t status) |
494 | { | 447 | { |
495 | if (friendlist[friendnumber].status != status && friend_statuschange_isset) | 448 | if (!m->friend_connectionstatuschange_isset) |
496 | friend_statuschange(friendnumber, status); | 449 | return; |
497 | friendlist[friendnumber].status = status; | 450 | if (status == NOFRIEND) |
451 | return; | ||
452 | const uint8_t was_connected = m->friendlist[friendnumber].status == FRIEND_ONLINE; | ||
453 | const uint8_t is_connected = status == FRIEND_ONLINE; | ||
454 | if (is_connected != was_connected) | ||
455 | m->friend_connectionstatuschange(m, friendnumber, is_connected); | ||
498 | } | 456 | } |
499 | 457 | ||
500 | static int write_cryptpacket_id(int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) | 458 | void set_friend_status(Messenger *m, int friendnumber, uint8_t status) |
501 | { | 459 | { |
502 | if (friendnumber < 0 || friendnumber >= numfriends) | 460 | check_friend_connectionstatus(m, friendnumber, status); |
461 | m->friendlist[friendnumber].status = status; | ||
462 | } | ||
463 | |||
464 | int write_cryptpacket_id(Messenger *m, int friendnumber, uint8_t packet_id, uint8_t *data, uint32_t length) | ||
465 | { | ||
466 | if (friendnumber < 0 || friendnumber >= m->numfriends) | ||
503 | return 0; | 467 | return 0; |
504 | if (length >= MAX_DATA_SIZE || friendlist[friendnumber].status != FRIEND_ONLINE) | 468 | if (length >= MAX_DATA_SIZE || m->friendlist[friendnumber].status != FRIEND_ONLINE) |
505 | return 0; | 469 | return 0; |
506 | uint8_t packet[length + 1]; | 470 | uint8_t packet[length + 1]; |
507 | packet[0] = packet_id; | 471 | packet[0] = packet_id; |
508 | memcpy(packet + 1, data, length); | 472 | memcpy(packet + 1, data, length); |
509 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, packet, length + 1); | 473 | return write_cryptpacket(m->friendlist[friendnumber].crypt_connection_id, packet, length + 1); |
510 | } | 474 | } |
511 | 475 | ||
512 | #define PORT 33445 | 476 | #define PORT 33445 |
513 | /* run this at startup */ | 477 | /* run this at startup */ |
514 | int initMessenger(void) | 478 | Messenger * initMessenger(void) |
515 | { | 479 | { |
480 | Messenger *m = calloc(1, sizeof(Messenger)); | ||
481 | if( ! m ) | ||
482 | return 0; | ||
483 | |||
516 | new_keys(); | 484 | new_keys(); |
517 | m_set_statusmessage((uint8_t*)"Online", sizeof("Online")); | 485 | m_set_statusmessage(m, (uint8_t*)"Online", sizeof("Online")); |
518 | initNetCrypto(); | 486 | initNetCrypto(); |
519 | IP ip; | 487 | IP ip; |
520 | ip.i = 0; | 488 | ip.i = 0; |
521 | 489 | ||
522 | if(init_networking(ip,PORT) == -1) | 490 | if(init_networking(ip,PORT) == -1) |
523 | return -1; | 491 | return 0; |
524 | 492 | ||
525 | DHT_init(); | 493 | DHT_init(); |
526 | LosslessUDP_init(); | 494 | LosslessUDP_init(); |
527 | friendreq_init(); | 495 | friendreq_init(); |
528 | LANdiscovery_init(); | 496 | LANdiscovery_init(); |
529 | 497 | ||
530 | return 0; | 498 | return m; |
499 | } | ||
500 | |||
501 | /* run this before closing shop */ | ||
502 | void cleanupMessenger(Messenger *m){ | ||
503 | /* FIXME TODO it seems no one frees friendlist or all the elements status */ | ||
504 | free(m); | ||
531 | } | 505 | } |
532 | 506 | ||
533 | //TODO: make this function not suck. | 507 | //TODO: make this function not suck. |
534 | static void doFriends(void) | 508 | void doFriends(Messenger *m) |
535 | { | 509 | { |
536 | /* TODO: add incoming connections and some other stuff. */ | 510 | /* TODO: add incoming connections and some other stuff. */ |
537 | uint32_t i; | 511 | uint32_t i; |
538 | int len; | 512 | int len; |
539 | uint8_t temp[MAX_DATA_SIZE]; | 513 | uint8_t temp[MAX_DATA_SIZE]; |
540 | for (i = 0; i < numfriends; ++i) { | 514 | for (i = 0; i < m->numfriends; ++i) { |
541 | if (friendlist[i].status == FRIEND_ADDED) { | 515 | if (m->friendlist[i].status == FRIEND_ADDED) { |
542 | int fr = send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); | 516 | int fr = send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size); |
543 | 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 */ | 517 | 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 */ |
544 | set_friend_status(i, FRIEND_REQUESTED); | 518 | set_friend_status(m, i, FRIEND_REQUESTED); |
545 | else if (fr > 0) | 519 | else if (fr > 0) |
546 | set_friend_status(i, FRIEND_REQUESTED); | 520 | set_friend_status(m, i, FRIEND_REQUESTED); |
547 | } | 521 | } |
548 | if (friendlist[i].status == FRIEND_REQUESTED || friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ | 522 | if (m->friendlist[i].status == FRIEND_REQUESTED || m->friendlist[i].status == FRIEND_CONFIRMED) { /* friend is not online */ |
549 | if (friendlist[i].status == FRIEND_REQUESTED) { | 523 | if (m->friendlist[i].status == FRIEND_REQUESTED) { |
550 | if (friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ | 524 | if (m->friendlist[i].friend_request_id + 10 < unix_time()) { /*I know this is hackish but it should work.*/ |
551 | send_friendrequest(friendlist[i].client_id, friendlist[i].info, friendlist[i].info_size); | 525 | send_friendrequest(m->friendlist[i].client_id, m->friendlist[i].info, m->friendlist[i].info_size); |
552 | friendlist[i].friend_request_id = unix_time(); | 526 | m->friendlist[i].friend_request_id = unix_time(); |
553 | } | 527 | } |
554 | } | 528 | } |
555 | IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); | 529 | IP_Port friendip = DHT_getfriendip(m->friendlist[i].client_id); |
556 | switch (is_cryptoconnected(friendlist[i].crypt_connection_id)) { | 530 | switch (is_cryptoconnected(m->friendlist[i].crypt_connection_id)) { |
557 | case 0: | 531 | case 0: |
558 | if (friendip.ip.i > 1) | 532 | if (friendip.ip.i > 1) |
559 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); | 533 | m->friendlist[i].crypt_connection_id = crypto_connect(m->friendlist[i].client_id, friendip); |
560 | break; | 534 | break; |
561 | case 3: /* Connection is established */ | 535 | case 3: /* Connection is established */ |
562 | set_friend_status(i, FRIEND_ONLINE); | 536 | set_friend_status(m, i, FRIEND_ONLINE); |
537 | m->friendlist[i].name_sent = 0; | ||
538 | m->friendlist[i].userstatus_sent = 0; | ||
539 | m->friendlist[i].statusmessage_sent = 0; | ||
563 | break; | 540 | break; |
564 | case 4: | 541 | case 4: |
565 | crypto_kill(friendlist[i].crypt_connection_id); | 542 | crypto_kill(m->friendlist[i].crypt_connection_id); |
566 | friendlist[i].crypt_connection_id = -1; | 543 | m->friendlist[i].crypt_connection_id = -1; |
567 | break; | 544 | break; |
568 | default: | 545 | default: |
569 | break; | 546 | break; |
570 | } | 547 | } |
571 | } | 548 | } |
572 | while (friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ | 549 | while (m->friendlist[i].status == FRIEND_ONLINE) { /* friend is online */ |
573 | if (friendlist[i].name_sent == 0) { | 550 | if (m->friendlist[i].name_sent == 0) { |
574 | if (m_sendname(i, self_name, self_name_length)) | 551 | if (m_sendname(m, i, m->name, m->name_length)) |
575 | friendlist[i].name_sent = 1; | 552 | m->friendlist[i].name_sent = 1; |
576 | } | 553 | } |
577 | if (friendlist[i].statusmessage_sent == 0) { | 554 | if (m->friendlist[i].statusmessage_sent == 0) { |
578 | if (send_statusmessage(i, self_statusmessage, self_statusmessage_length)) | 555 | if (send_statusmessage(m, i, m->statusmessage, m->statusmessage_length)) |
579 | friendlist[i].statusmessage_sent = 1; | 556 | m->friendlist[i].statusmessage_sent = 1; |
580 | } | 557 | } |
581 | if (friendlist[i].userstatus_sent == 0) { | 558 | if (m->friendlist[i].userstatus_sent == 0) { |
582 | if (send_userstatus(i, self_userstatus)) | 559 | if (send_userstatus(m, i, m->userstatus)) |
583 | friendlist[i].userstatus_sent = 1; | 560 | m->friendlist[i].userstatus_sent = 1; |
584 | } | 561 | } |
585 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); | 562 | len = read_cryptpacket(m->friendlist[i].crypt_connection_id, temp); |
586 | uint8_t packet_id = temp[0]; | 563 | uint8_t packet_id = temp[0]; |
587 | uint8_t* data = temp + 1; | 564 | uint8_t* data = temp + 1; |
588 | int data_length = len - 1; | 565 | int data_length = len - 1; |
@@ -591,10 +568,10 @@ static void doFriends(void) | |||
591 | case PACKET_ID_NICKNAME: { | 568 | case PACKET_ID_NICKNAME: { |
592 | if (data_length >= MAX_NAME_LENGTH || data_length == 0) | 569 | if (data_length >= MAX_NAME_LENGTH || data_length == 0) |
593 | break; | 570 | break; |
594 | if(friend_namechange_isset) | 571 | if(m->friend_namechange_isset) |
595 | friend_namechange(i, data, data_length); | 572 | m->friend_namechange(m, i, data, data_length); |
596 | memcpy(friendlist[i].name, data, data_length); | 573 | memcpy(m->friendlist[i].name, data, data_length); |
597 | friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ | 574 | m->friendlist[i].name[data_length - 1] = 0; /* make sure the NULL terminator is present. */ |
598 | break; | 575 | break; |
599 | } | 576 | } |
600 | case PACKET_ID_STATUSMESSAGE: { | 577 | case PACKET_ID_STATUSMESSAGE: { |
@@ -602,9 +579,9 @@ static void doFriends(void) | |||
602 | break; | 579 | break; |
603 | uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); | 580 | uint8_t *status = calloc(MIN(data_length, MAX_STATUSMESSAGE_LENGTH), 1); |
604 | memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); | 581 | memcpy(status, data, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
605 | if (friend_statusmessagechange_isset) | 582 | if (m->friend_statusmessagechange_isset) |
606 | friend_statusmessagechange(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); | 583 | m->friend_statusmessagechange(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
607 | set_friend_statusmessage(i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); | 584 | set_friend_statusmessage(m, i, status, MIN(data_length, MAX_STATUSMESSAGE_LENGTH)); |
608 | free(status); | 585 | free(status); |
609 | break; | 586 | break; |
610 | } | 587 | } |
@@ -612,9 +589,9 @@ static void doFriends(void) | |||
612 | if (data_length != 1) | 589 | if (data_length != 1) |
613 | break; | 590 | break; |
614 | USERSTATUS status = data[0]; | 591 | USERSTATUS status = data[0]; |
615 | if (friend_userstatuschange_isset) | 592 | if (m->friend_userstatuschange_isset) |
616 | friend_userstatuschange(i, status); | 593 | m->friend_userstatuschange(m, i, status); |
617 | set_friend_userstatus(i, status); | 594 | set_friend_userstatus(m, i, status); |
618 | break; | 595 | break; |
619 | } | 596 | } |
620 | case PACKET_ID_MESSAGE: { | 597 | case PACKET_ID_MESSAGE: { |
@@ -622,16 +599,16 @@ static void doFriends(void) | |||
622 | uint8_t message_id_length = 4; | 599 | uint8_t message_id_length = 4; |
623 | uint8_t *message = data + message_id_length; | 600 | uint8_t *message = data + message_id_length; |
624 | uint16_t message_length = data_length - message_id_length; | 601 | uint16_t message_length = data_length - message_id_length; |
625 | if (friendlist[i].receives_read_receipts) { | 602 | if (m->friendlist[i].receives_read_receipts) { |
626 | write_cryptpacket_id(i, PACKET_ID_RECEIPT, message_id, message_id_length); | 603 | write_cryptpacket_id(m, i, PACKET_ID_RECEIPT, message_id, message_id_length); |
627 | } | 604 | } |
628 | if (friend_message_isset) | 605 | if (m->friend_message_isset) |
629 | (*friend_message)(i, message, message_length); | 606 | (*m->friend_message)(m, i, message, message_length); |
630 | break; | 607 | break; |
631 | } | 608 | } |
632 | case PACKET_ID_ACTION: { | 609 | case PACKET_ID_ACTION: { |
633 | if (friend_action_isset) | 610 | if (m->friend_action_isset) |
634 | (*friend_action)(i, data, data_length); | 611 | (*m->friend_action)(m, i, data, data_length); |
635 | break; | 612 | break; |
636 | } | 613 | } |
637 | case PACKET_ID_RECEIPT: { | 614 | case PACKET_ID_RECEIPT: { |
@@ -640,16 +617,16 @@ static void doFriends(void) | |||
640 | break; | 617 | break; |
641 | memcpy(&msgid, data, sizeof(msgid)); | 618 | memcpy(&msgid, data, sizeof(msgid)); |
642 | msgid = ntohl(msgid); | 619 | msgid = ntohl(msgid); |
643 | if (read_receipt_isset) | 620 | if (m->read_receipt_isset) |
644 | (*read_receipt)(i, msgid); | 621 | (*m->read_receipt)(m, i, msgid); |
645 | break; | 622 | break; |
646 | } | 623 | } |
647 | } | 624 | } |
648 | } else { | 625 | } else { |
649 | if (is_cryptoconnected(friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ | 626 | if (is_cryptoconnected(m->friendlist[i].crypt_connection_id) == 4) { /* if the connection timed out, kill it */ |
650 | crypto_kill(friendlist[i].crypt_connection_id); | 627 | crypto_kill(m->friendlist[i].crypt_connection_id); |
651 | friendlist[i].crypt_connection_id = -1; | 628 | m->friendlist[i].crypt_connection_id = -1; |
652 | set_friend_status(i, FRIEND_CONFIRMED); | 629 | set_friend_status(m, i, FRIEND_CONFIRMED); |
653 | } | 630 | } |
654 | break; | 631 | break; |
655 | } | 632 | } |
@@ -657,20 +634,20 @@ static void doFriends(void) | |||
657 | } | 634 | } |
658 | } | 635 | } |
659 | 636 | ||
660 | static void doInbound(void) | 637 | void doInbound(Messenger *m) |
661 | { | 638 | { |
662 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; | 639 | uint8_t secret_nonce[crypto_box_NONCEBYTES]; |
663 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | 640 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; |
664 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; | 641 | uint8_t session_key[crypto_box_PUBLICKEYBYTES]; |
665 | int inconnection = crypto_inbound(public_key, secret_nonce, session_key); | 642 | int inconnection = crypto_inbound(public_key, secret_nonce, session_key); |
666 | if (inconnection != -1) { | 643 | if (inconnection != -1) { |
667 | int friend_id = getfriend_id(public_key); | 644 | int friend_id = getfriend_id(m, public_key); |
668 | if (friend_id != -1) { | 645 | if (friend_id != -1) { |
669 | crypto_kill(friendlist[friend_id].crypt_connection_id); | 646 | crypto_kill(m->friendlist[friend_id].crypt_connection_id); |
670 | friendlist[friend_id].crypt_connection_id = | 647 | m->friendlist[friend_id].crypt_connection_id = |
671 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); | 648 | accept_crypto_inbound(inconnection, public_key, secret_nonce, session_key); |
672 | 649 | ||
673 | set_friend_status(friend_id, FRIEND_CONFIRMED); | 650 | set_friend_status(m, friend_id, FRIEND_CONFIRMED); |
674 | } | 651 | } |
675 | } | 652 | } |
676 | } | 653 | } |
@@ -681,7 +658,7 @@ static void doInbound(void) | |||
681 | static uint64_t last_LANdiscovery; | 658 | static uint64_t last_LANdiscovery; |
682 | 659 | ||
683 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ | 660 | /*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/ |
684 | static void LANdiscovery(void) | 661 | void LANdiscovery(Messenger *m) |
685 | { | 662 | { |
686 | if (last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { | 663 | if (last_LANdiscovery + LAN_DISCOVERY_INTERVAL < unix_time()) { |
687 | send_LANdiscovery(htons(PORT)); | 664 | send_LANdiscovery(htons(PORT)); |
@@ -691,27 +668,27 @@ static void LANdiscovery(void) | |||
691 | 668 | ||
692 | 669 | ||
693 | /* the main loop that needs to be run at least 200 times per second. */ | 670 | /* the main loop that needs to be run at least 200 times per second. */ |
694 | void doMessenger(void) | 671 | void doMessenger(Messenger *m) |
695 | { | 672 | { |
696 | networking_poll(); | 673 | networking_poll(); |
697 | 674 | ||
698 | doDHT(); | 675 | doDHT(); |
699 | doLossless_UDP(); | 676 | doLossless_UDP(); |
700 | doNetCrypto(); | 677 | doNetCrypto(); |
701 | doInbound(); | 678 | doInbound(m); |
702 | doFriends(); | 679 | doFriends(m); |
703 | LANdiscovery(); | 680 | LANdiscovery(m); |
704 | } | 681 | } |
705 | 682 | ||
706 | /* returns the size of the messenger data (for saving) */ | 683 | /* returns the size of the messenger data (for saving) */ |
707 | uint32_t Messenger_size(void) | 684 | uint32_t Messenger_size(Messenger *m) |
708 | { | 685 | { |
709 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES | 686 | return crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES |
710 | + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * numfriends; | 687 | + sizeof(uint32_t) + DHT_size() + sizeof(uint32_t) + sizeof(Friend) * m->numfriends; |
711 | } | 688 | } |
712 | 689 | ||
713 | /* save the messenger in data of size Messenger_size() */ | 690 | /* save the messenger in data of size Messenger_size() */ |
714 | void Messenger_save(uint8_t *data) | 691 | void Messenger_save(Messenger *m, uint8_t *data) |
715 | { | 692 | { |
716 | save_keys(data); | 693 | save_keys(data); |
717 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; | 694 | data += crypto_box_PUBLICKEYBYTES + crypto_box_SECRETKEYBYTES; |
@@ -720,14 +697,14 @@ void Messenger_save(uint8_t *data) | |||
720 | data += sizeof(size); | 697 | data += sizeof(size); |
721 | DHT_save(data); | 698 | DHT_save(data); |
722 | data += size; | 699 | data += size; |
723 | size = sizeof(Friend) * numfriends; | 700 | size = sizeof(Friend) * m->numfriends; |
724 | memcpy(data, &size, sizeof(size)); | 701 | memcpy(data, &size, sizeof(size)); |
725 | data += sizeof(size); | 702 | data += sizeof(size); |
726 | memcpy(data, friendlist, sizeof(Friend) * numfriends); | 703 | memcpy(data, m->friendlist, sizeof(Friend) * m->numfriends); |
727 | } | 704 | } |
728 | 705 | ||
729 | /* load the messenger from data of size length. */ | 706 | /* load the messenger from data of size length. */ |
730 | int Messenger_load(uint8_t * data, uint32_t length) | 707 | int Messenger_load(Messenger *m, uint8_t * data, uint32_t length) |
731 | { | 708 | { |
732 | if (length == ~0) | 709 | if (length == ~0) |
733 | return -1; | 710 | return -1; |
@@ -759,11 +736,12 @@ int Messenger_load(uint8_t * data, uint32_t length) | |||
759 | uint32_t i; | 736 | uint32_t i; |
760 | for (i = 0; i < num; ++i) { | 737 | for (i = 0; i < num; ++i) { |
761 | if(temp[i].status != 0) { | 738 | if(temp[i].status != 0) { |
762 | int fnum = m_addfriend_norequest(temp[i].client_id); | 739 | int fnum = m_addfriend_norequest(m, temp[i].client_id); |
763 | setfriendname(fnum, temp[i].name); | 740 | setfriendname(m, fnum, temp[i].name); |
764 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ | 741 | /* set_friend_statusmessage(fnum, temp[i].statusmessage, temp[i].statusmessage_length); */ |
765 | } | 742 | } |
766 | } | 743 | } |
767 | free(temp); | 744 | free(temp); |
768 | return 0; | 745 | return 0; |
769 | } | 746 | } |
747 | |||