diff options
-rw-r--r-- | core/DHT.c | 4 | ||||
-rw-r--r-- | core/Messenger.c | 174 | ||||
-rw-r--r-- | core/Messenger.h | 18 | ||||
-rw-r--r-- | testing/Messenger_test.c | 92 |
4 files changed, 260 insertions, 28 deletions
@@ -756,7 +756,7 @@ int DHT_handlepacket(uint8_t * packet, uint32_t length, IP_Port source) | |||
756 | static uint32_t friend_lastgetnode[MAX_FRIENDS]; | 756 | static uint32_t friend_lastgetnode[MAX_FRIENDS]; |
757 | 757 | ||
758 | 758 | ||
759 | void doFriends() | 759 | void doDHTFriends() |
760 | { | 760 | { |
761 | uint32_t i, j; | 761 | uint32_t i, j; |
762 | uint32_t temp_time = unix_time(); | 762 | uint32_t temp_time = unix_time(); |
@@ -836,7 +836,7 @@ void doClose()//tested | |||
836 | void doDHT() | 836 | void doDHT() |
837 | { | 837 | { |
838 | doClose(); | 838 | doClose(); |
839 | doFriends(); | 839 | doDHTFriends(); |
840 | } | 840 | } |
841 | 841 | ||
842 | 842 | ||
diff --git a/core/Messenger.c b/core/Messenger.c index 7cfbb8ca..1107b60f 100644 --- a/core/Messenger.c +++ b/core/Messenger.c | |||
@@ -10,71 +10,203 @@ | |||
10 | typedef struct | 10 | typedef struct |
11 | { | 11 | { |
12 | uint8_t client_id[CLIENT_ID_SIZE]; | 12 | uint8_t client_id[CLIENT_ID_SIZE]; |
13 | 13 | int crypt_connection_id; | |
14 | int friend_request_id; //id of the friend request corresponding to the current friend request to the current friend. | ||
15 | uint8_t status;//0 if no friend, 1 if added, 2 if friend request successfully sent, 3 if confirmed friend, 4 if online. | ||
14 | 16 | ||
15 | }Friend; | 17 | }Friend; |
16 | 18 | ||
19 | |||
20 | uint8_t info[MAX_DATA_SIZE]; //the data that is sent during the friend requests we do | ||
21 | |||
22 | uint16_t info_size; //length of the info | ||
23 | |||
17 | #define MAX_NUM_FRIENDS 256 | 24 | #define MAX_NUM_FRIENDS 256 |
18 | 25 | ||
19 | Friend friendlist[MAX_NUM_FRIENDS]; | 26 | Friend friendlist[MAX_NUM_FRIENDS]; |
27 | |||
28 | #define MAX_MESSAGE_LENGTH 256 | ||
29 | |||
30 | uint32_t numfriends; | ||
20 | 31 | ||
21 | //add a friend | 32 | //add a friend |
33 | //client_id is the client i of the friend | ||
22 | //returns the friend number if success | 34 | //returns the friend number if success |
23 | //return -1 if failure. | 35 | //return -1 if failure. |
24 | int m_addfriend(uint8_t * client_id) | 36 | int m_addfriend(uint8_t * client_id) |
25 | { | 37 | { |
26 | 38 | ||
27 | //add friend to the DHT | 39 | DHT_addfriend(client_id); |
28 | addfriend(uint8_t * client_id); | 40 | friendlist[numfriends].status = 1; |
29 | 41 | friendlist[numfriends].friend_request_id = -1; | |
30 | send_friendrequest(uint8_t * public_key, IP_Port ip_port, uint8_t * data, uint32_t length); | 42 | memcpy(friendlist[numfriends].client_id, client_id, CLIENT_ID_SIZE); |
43 | numfriends++; | ||
31 | 44 | ||
45 | return numfriends - 1; | ||
32 | } | 46 | } |
33 | 47 | ||
34 | //remove a friend | 48 | //remove a friend |
35 | int m_delfriend(int friendnumber) | 49 | int m_delfriend(int friendnumber) |
50 | {/* | ||
51 | TODO | ||
52 | DHT_delfriend(friendlist[friendnumber].client_id); | ||
53 | */ | ||
54 | } | ||
55 | |||
56 | |||
57 | //return 4 if friend is online | ||
58 | //return 3 if friend is confirmed | ||
59 | //return 2 if the friend request was sent successfully | ||
60 | //return 1 if the friend was added | ||
61 | //return 0 if there is no friend with that number. | ||
62 | int m_friendstatus(int friendnumber) | ||
36 | { | 63 | { |
37 | //delete friend from DHT | 64 | if(friendnumber < 0 || friendnumber >= MAX_NUM_FRIENDS) |
38 | delfriend(uint8_t * client_id); | 65 | { |
39 | 66 | return 0; | |
67 | } | ||
68 | return friendlist[friendnumber].status; | ||
40 | } | 69 | } |
41 | 70 | ||
42 | 71 | ||
43 | //return 1 if friend is online | 72 | //send a text chat message to an online friend. |
44 | //return 0 if he is not | 73 | //returns 1 if packet was successfully put into the send queue |
45 | int m_friendonline(int friendnumber) | 74 | //return 0 if it was not. |
75 | int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length) | ||
46 | { | 76 | { |
47 | 77 | if(length >= MAX_DATA_SIZE) | |
78 | //this does not mean the maximum message length is MAX_DATA_SIZE - 1, it is actually 17 bytes less. | ||
79 | { | ||
80 | return 0; | ||
81 | } | ||
82 | uint8_t temp[MAX_DATA_SIZE]; | ||
83 | temp[0] = 64; | ||
84 | memcpy(temp + 1, message, length); | ||
85 | return write_cryptpacket(friendlist[friendnumber].crypt_connection_id, temp, length + 1); | ||
48 | 86 | ||
49 | } | 87 | } |
50 | 88 | ||
89 | //set the data that will be sent along with friend requests | ||
90 | //return -1 if failure | ||
91 | //return 0 if success | ||
92 | int m_setinfo(uint8_t * data, uint16_t length) | ||
93 | { | ||
94 | if(length == 0 || length > MAX_DATA_SIZE - 1 - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES) | ||
95 | { | ||
96 | return -1; | ||
97 | } | ||
98 | memcpy(info, data, length); | ||
99 | info_size = length; | ||
100 | return 0; | ||
101 | } | ||
51 | 102 | ||
52 | //send a text chat message to a friend. | 103 | void (*friend_request)(uint8_t *, uint8_t *, uint16_t); |
53 | int m_sendmessage(int friendnumber) | 104 | |
105 | //set the function that will be executed when a friend request is received. | ||
106 | int m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)) | ||
54 | { | 107 | { |
55 | write_cryptpacket(int crypt_connection_id, uint8_t * data, uint32_t length); | 108 | friend_request = function; |
56 | 109 | } | |
110 | |||
111 | |||
112 | void (*friend_message)(int, uint8_t *, uint16_t); | ||
113 | |||
114 | //set the function that will be executed when a message from a friend is received. | ||
115 | int m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)) | ||
116 | { | ||
117 | friend_message = function; | ||
57 | } | 118 | } |
58 | 119 | ||
59 | 120 | ||
60 | #define PORT 33445 | 121 | #define PORT 33445 |
61 | //run this at startup | 122 | //run this at startup |
62 | void initMessenger(); | 123 | void initMessenger() |
63 | { | 124 | { |
64 | new_keys(); | 125 | new_keys(); |
126 | initNetCrypto(); | ||
65 | IP ip; | 127 | IP ip; |
66 | ip.i = 0; | 128 | ip.i = 0; |
67 | init_networking(ip, PORT); | 129 | init_networking(ip, PORT); |
130 | memcpy(self_client_id, self_public_key, crypto_box_PUBLICKEYBYTES); | ||
68 | 131 | ||
69 | } | 132 | } |
70 | 133 | ||
134 | void doFriends() | ||
135 | {//TODO: add incoming connections and some other stuff. | ||
136 | uint32_t i; | ||
137 | int len; | ||
138 | uint8_t temp[MAX_DATA_SIZE]; | ||
139 | for(i = 0; i < numfriends; i++) | ||
140 | { | ||
141 | if(friendlist[i].status == 1) | ||
142 | { | ||
143 | IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); | ||
144 | int request = check_friendrequest(friendlist[i].friend_request_id); | ||
145 | //printf("\n%u %u %u\n", friendip.ip.i, request, friendlist[i].friend_request_id); | ||
146 | if(friendip.ip.i > 1 && request == -1) | ||
147 | { | ||
148 | friendlist[i].friend_request_id = send_friendrequest(friendlist[i].client_id, friendip, info, info_size); | ||
149 | } | ||
150 | if(request == 1) | ||
151 | { | ||
152 | friendlist[i].status = 2; | ||
153 | } | ||
154 | } | ||
155 | if(friendlist[i].status == 2 || friendlist[i].status == 3) | ||
156 | { | ||
157 | IP_Port friendip = DHT_getfriendip(friendlist[i].client_id); | ||
158 | if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 0 && friendip.ip.i > 1) | ||
159 | { | ||
160 | friendlist[i].crypt_connection_id = crypto_connect(friendlist[i].client_id, friendip); | ||
161 | } | ||
162 | if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 3)//if connection is established. | ||
163 | { | ||
164 | friendlist[i].status = 4; | ||
165 | } | ||
166 | } | ||
167 | while(friendlist[i].status == 4) | ||
168 | { | ||
169 | len = read_cryptpacket(friendlist[i].crypt_connection_id, temp); | ||
170 | if(len > 0) | ||
171 | { | ||
172 | if(temp[0] == 64) | ||
173 | { | ||
174 | (*friend_message)(i, temp, len); | ||
175 | } | ||
176 | } | ||
177 | else | ||
178 | { | ||
179 | if(is_cryptoconnected(friendlist[i].crypt_connection_id) == 4)//if the connection timed out, kill it | ||
180 | { | ||
181 | crypto_kill(friendlist[i].crypt_connection_id); | ||
182 | friendlist[i].status = 3; | ||
183 | } | ||
184 | break; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | } | ||
189 | |||
190 | void doFriendRequest() | ||
191 | { | ||
192 | uint8_t public_key[crypto_box_PUBLICKEYBYTES]; | ||
193 | uint8_t temp[MAX_DATA_SIZE]; | ||
194 | |||
195 | int len = handle_friendrequest(public_key, temp); | ||
196 | if(len >= 0) | ||
197 | { | ||
198 | (*friend_request)(public_key, temp, len); | ||
199 | |||
200 | } | ||
201 | |||
202 | } | ||
71 | //the main loop that needs to be run at least 200 times per second. | 203 | //the main loop that needs to be run at least 200 times per second. |
72 | void doMessenger(); | 204 | void doMessenger() |
73 | { | 205 | { |
74 | IP_Port ip_port; | 206 | IP_Port ip_port; |
75 | uint8_t data[MAX_UDP_PACKET_SIZE]; | 207 | uint8_t data[MAX_UDP_PACKET_SIZE]; |
76 | uint32_t length; | 208 | uint32_t length; |
77 | while(recievepacket(&ip_port, data, &length) != -1) | 209 | while(receivepacket(&ip_port, data, &length) != -1) |
78 | { | 210 | { |
79 | //if(rand() % 3 != 1)//simulate packet loss | 211 | //if(rand() % 3 != 1)//simulate packet loss |
80 | //{ | 212 | //{ |
@@ -92,4 +224,6 @@ void doMessenger(); | |||
92 | doDHT(); | 224 | doDHT(); |
93 | doLossless_UDP(); | 225 | doLossless_UDP(); |
94 | doNetCrypto(); | 226 | doNetCrypto(); |
95 | } \ No newline at end of file | 227 | doFriendRequest(); |
228 | doFriends(); | ||
229 | } | ||
diff --git a/core/Messenger.h b/core/Messenger.h index ae8ace16..1032d8d8 100644 --- a/core/Messenger.h +++ b/core/Messenger.h | |||
@@ -23,19 +23,25 @@ int m_delfriend(int friendnumber); | |||
23 | 23 | ||
24 | //return 1 if friend is online | 24 | //return 1 if friend is online |
25 | //return 0 if he is not | 25 | //return 0 if he is not |
26 | int m_friendonline(int friendnumber); | 26 | int m_friendstatus(int friendnumber); |
27 | 27 | ||
28 | 28 | ||
29 | //send a text chat message to a friend. | 29 | //send a text chat message to a friend. |
30 | int m_sendmessage(int friendnumber); | 30 | int m_sendmessage(int friendnumber, uint8_t * message, uint32_t length); |
31 | 31 | ||
32 | //set the data that will be sent along with friend requests | ||
33 | //return -1 if failure | ||
34 | //return 0 if success | ||
35 | int m_setinfo(uint8_t * data, uint16_t length); | ||
32 | 36 | ||
33 | //set the function that will be executed when a friend request is recieved. | 37 | //set the function that will be executed when a friend request is received. |
34 | int m_callback_friendrequest(); | 38 | //function format is function(uint8_t * public_key, uint8_t * data, uint16_t length) |
39 | int m_callback_friendrequest(void (*function)(uint8_t *, uint8_t *, uint16_t)); | ||
35 | 40 | ||
36 | 41 | ||
37 | //set the function that will be executed when a message from a friend is recieved. | 42 | //set the function that will be executed when a message from a friend is received. |
38 | int m_callback_friendmessage(); | 43 | //function format is: function(int friendnumber, uint8_t * message, uint32_t length) |
44 | int m_callback_friendmessage(void (*function)(int, uint8_t *, uint16_t)); | ||
39 | 45 | ||
40 | 46 | ||
41 | //run this at startup | 47 | //run this at startup |
diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c new file mode 100644 index 00000000..4290d0fa --- /dev/null +++ b/testing/Messenger_test.c | |||
@@ -0,0 +1,92 @@ | |||
1 | |||
2 | |||
3 | #include "../core/Messenger.h" | ||
4 | |||
5 | #ifdef WIN32 | ||
6 | |||
7 | #define c_sleep(x) Sleep(1*x) | ||
8 | |||
9 | #else | ||
10 | #include <unistd.h> | ||
11 | #include <arpa/inet.h> | ||
12 | #define c_sleep(x) usleep(1000*x) | ||
13 | |||
14 | #endif | ||
15 | |||
16 | //horrible function from one of my first C programs. | ||
17 | //only here because I was too lazy to write a proper one. | ||
18 | unsigned char * hex_string_to_bin(char hex_string[]) | ||
19 | { | ||
20 | unsigned char * val = malloc(strlen(hex_string)); | ||
21 | char * pos = hex_string; | ||
22 | int i=0; | ||
23 | while(i < strlen(hex_string)) | ||
24 | { | ||
25 | sscanf(pos,"%2hhx",&val[i]); | ||
26 | pos+=2; | ||
27 | i++; | ||
28 | } | ||
29 | return val; | ||
30 | } | ||
31 | |||
32 | void print_request(uint8_t * public_key, uint8_t * data, uint16_t length) | ||
33 | { | ||
34 | printf("Friend request recieved from: \n"); | ||
35 | printf("ClientID: "); | ||
36 | uint32_t j; | ||
37 | for(j = 0; j < 32; j++) | ||
38 | { | ||
39 | if(public_key[j] < 16) | ||
40 | printf("0"); | ||
41 | printf("%hhX", public_key[j]); | ||
42 | } | ||
43 | printf("\nOf length: %u with data: %s \n", length, data); | ||
44 | |||
45 | } | ||
46 | |||
47 | void print_message(int friendnumber, uint8_t * string, uint16_t length) | ||
48 | { | ||
49 | printf("Message with length %u recieved from %u: %s \n", length, friendnumber, string); | ||
50 | |||
51 | } | ||
52 | |||
53 | int main(int argc, char *argv[]) | ||
54 | { | ||
55 | if (argc < 3) { | ||
56 | printf("usage %s ip port (of the DHT bootstrap node)\n", argv[0]); | ||
57 | exit(0); | ||
58 | } | ||
59 | initMessenger(); | ||
60 | m_callback_friendrequest(print_request); | ||
61 | m_callback_friendmessage(print_message); | ||
62 | |||
63 | m_setinfo("Install Gentoo", sizeof("Install Gentoo"));//The message we send is a message of peace | ||
64 | |||
65 | printf("OUR ID: "); | ||
66 | uint32_t i; | ||
67 | for(i = 0; i < 32; i++) | ||
68 | { | ||
69 | if(self_public_key[i] < 16) | ||
70 | printf("0"); | ||
71 | printf("%hhX",self_public_key[i]); | ||
72 | } | ||
73 | |||
74 | char temp_id[128]; | ||
75 | printf("\nEnter the client_id of the friend you wish to add (32 bytes HEX format):\n"); | ||
76 | scanf("%s", temp_id); | ||
77 | int num = m_addfriend(hex_string_to_bin(temp_id)); | ||
78 | |||
79 | perror("Initialization"); | ||
80 | IP_Port bootstrap_ip_port; | ||
81 | bootstrap_ip_port.port = htons(atoi(argv[2])); | ||
82 | bootstrap_ip_port.ip.i = inet_addr(argv[1]); | ||
83 | DHT_bootstrap(bootstrap_ip_port); | ||
84 | |||
85 | while(1) | ||
86 | { | ||
87 | m_sendmessage(num, "Test", 5); | ||
88 | doMessenger(); | ||
89 | c_sleep(1); | ||
90 | } | ||
91 | |||
92 | } | ||