mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
More groupchats code written.
This commit is contained in:
parent
ebdfa892b3
commit
d5d84818fe
|
@ -135,8 +135,7 @@ typedef struct {
|
|||
NAT nat;
|
||||
} DHT_Friend;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
IP_Port ip_port;
|
||||
}
|
||||
|
|
|
@ -1014,22 +1014,20 @@ static int write_cryptpacket_id(const Messenger *m, int32_t friendnumber, uint8_
|
|||
|
||||
/* Set the callback for group invites.
|
||||
*
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
|
||||
*/
|
||||
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number)
|
||||
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t))
|
||||
{
|
||||
m->group_invite = function;
|
||||
m->group_invite_number = number;
|
||||
}
|
||||
|
||||
/* Set the callback for group messages.
|
||||
*
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
|
||||
*/
|
||||
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number)
|
||||
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t))
|
||||
{
|
||||
m->group_message = function;
|
||||
m->group_message_number = number;
|
||||
}
|
||||
|
||||
/* Send a group invite packet.
|
||||
|
@ -2179,7 +2177,7 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
break;
|
||||
|
||||
if (m->group_invite)
|
||||
(*m->group_invite)(m, i, temp, len, m->group_invite_number);
|
||||
(*m->group_invite)(m, i, data, data_length);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -2189,7 +2187,8 @@ static int handle_packet(void *object, int i, uint8_t *temp, uint16_t len)
|
|||
break;
|
||||
|
||||
if (m->group_message)
|
||||
(*m->group_message)(m, i, temp, len, m->group_message_number);
|
||||
(*m->group_message)(m, i, data, data_length);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -300,10 +300,8 @@ typedef struct Messenger {
|
|||
void (*avatar_data_recv)(struct Messenger *m, int32_t, uint8_t, uint8_t *, uint8_t *, uint32_t, void *);
|
||||
|
||||
void *group_chat_object; /* Set by new_groupchats()*/
|
||||
void (*group_invite)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t);
|
||||
uint32_t group_invite_number;
|
||||
void (*group_message)(struct Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t);
|
||||
uint32_t group_message_number;
|
||||
void (*group_invite)(struct Messenger *m, int32_t, const uint8_t *, uint16_t);
|
||||
void (*group_message)(struct Messenger *m, int32_t, const uint8_t *, uint16_t);
|
||||
|
||||
void (*file_sendrequest)(struct Messenger *m, int32_t, uint8_t, uint64_t, const uint8_t *, uint16_t, void *);
|
||||
void *file_sendrequest_userdata;
|
||||
|
@ -735,15 +733,15 @@ void m_callback_avatar_data(Messenger *m, void (*function)(Messenger *m, int32_t
|
|||
|
||||
/* Set the callback for group invites.
|
||||
*
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
|
||||
*/
|
||||
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number);
|
||||
void m_callback_group_invite(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t));
|
||||
|
||||
/* Set the callback for group messages.
|
||||
*
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length, uint32_t number)
|
||||
* Function(Messenger *m, int32_t friendnumber, uint8_t *data, uint16_t length)
|
||||
*/
|
||||
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t, uint32_t), uint32_t number);
|
||||
void m_callback_group_message(Messenger *m, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t));
|
||||
|
||||
/* Send a group invite packet.
|
||||
*
|
||||
|
|
221
toxcore/group.c
221
toxcore/group.c
|
@ -248,6 +248,25 @@ static int peer_in_chat(const Group_c *chat, const uint8_t *client_id)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* check if group with identifier is in group array.
|
||||
*
|
||||
* return group number if peer is in list.
|
||||
* return -1 if group is not in list.
|
||||
*
|
||||
* TODO: make this more efficient and maybe use constant time comparisons?
|
||||
*/
|
||||
static int get_group_num(const Group_Chats *g_c, const uint8_t *identifier)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < g_c->num_chats; ++i)
|
||||
if (memcmp(g_c->chats[i].identifier, identifier, GROUP_IDENTIFIER_LENGTH) == 0)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a peer to the group chat.
|
||||
*
|
||||
|
@ -287,20 +306,162 @@ static int addpeer(Group_c *chat, const uint8_t *client_id)
|
|||
* return group number on success.
|
||||
* return -1 on failure.
|
||||
*/
|
||||
int temp_c_add_groupchat(Group_Chats *g_c)
|
||||
int add_groupchat(Group_Chats *g_c)
|
||||
{
|
||||
int groupnumber = create_group_chat(g_c);
|
||||
|
||||
Group_c *g = get_group_c(g_c, groupnumber);
|
||||
|
||||
if (!g) {
|
||||
if (!g)
|
||||
return -1;
|
||||
}
|
||||
|
||||
g->status = GROUPCHAT_STATUS_VALID;
|
||||
new_symmetric_key(g->identifier);
|
||||
return groupnumber;
|
||||
}
|
||||
|
||||
#define INVITE_PACKET_SIZE (1 + sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH)
|
||||
#define INVITE_ID 0
|
||||
|
||||
#define INVITE_RESPONSE_PACKET_SIZE (1 + sizeof(uint16_t) * 2 + GROUP_IDENTIFIER_LENGTH)
|
||||
#define INVITE_RESPONSE_ID 1
|
||||
|
||||
/* invite friendnumber to groupnumber
|
||||
* return 0 on success
|
||||
* return -1 on failure
|
||||
*/
|
||||
int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber)
|
||||
{
|
||||
Group_c *g = get_group_c(g_c, groupnumber);
|
||||
|
||||
if (!g)
|
||||
return -1;
|
||||
|
||||
uint8_t invite[INVITE_PACKET_SIZE];
|
||||
invite[0] = INVITE_ID;
|
||||
uint16_t groupchat_num = htons((uint16_t)groupnumber);
|
||||
memcpy(invite + 1, &groupchat_num, sizeof(groupchat_num));
|
||||
memcpy(invite + 1 + sizeof(groupchat_num), g->identifier, GROUP_IDENTIFIER_LENGTH);
|
||||
|
||||
if (send_group_invite_packet(g_c->m, friendnumber, invite, sizeof(invite))) {
|
||||
return 0;
|
||||
} else {
|
||||
wipe_group_chat(g_c, groupnumber);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Join a group (you need to have been invited first.)
|
||||
*
|
||||
* returns group number on success
|
||||
* returns -1 on failure.
|
||||
*/
|
||||
int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length != sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH)
|
||||
return -1;
|
||||
|
||||
int groupnumber = create_group_chat(g_c);
|
||||
|
||||
Group_c *g = get_group_c(g_c, groupnumber);
|
||||
|
||||
if (!g)
|
||||
return -1;
|
||||
|
||||
uint16_t group_num = htons(groupnumber);
|
||||
g->status = GROUPCHAT_STATUS_VALID;
|
||||
uint8_t response[INVITE_RESPONSE_PACKET_SIZE];
|
||||
response[0] = INVITE_RESPONSE_ID;
|
||||
memcpy(response + 1, &group_num, sizeof(uint16_t));
|
||||
memcpy(response + 1 + sizeof(uint16_t), data, sizeof(uint16_t) + GROUP_IDENTIFIER_LENGTH);
|
||||
|
||||
if (send_group_invite_packet(g_c->m, friendnumber, response, sizeof(response))) {
|
||||
uint16_t other_groupnum;
|
||||
memcpy(&other_groupnum, data, sizeof(other_groupnum));
|
||||
other_groupnum = htons(other_groupnum);
|
||||
//TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum);
|
||||
return groupnumber;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the callback for group invites.
|
||||
*
|
||||
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
|
||||
*
|
||||
* data of length is what needs to be passed to join_groupchat().
|
||||
*/
|
||||
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t,
|
||||
void *), void *userdata)
|
||||
{
|
||||
g_c->invite_callback = function;
|
||||
g_c->invite_callback_userdata = userdata;
|
||||
}
|
||||
|
||||
/* Set the callback for group messages.
|
||||
*
|
||||
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
|
||||
*/
|
||||
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
|
||||
void *), void *userdata)
|
||||
{
|
||||
g_c->message_callback = function;
|
||||
g_c->message_callback_userdata = userdata;
|
||||
}
|
||||
|
||||
static void handle_friend_invite_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
Group_Chats *g_c = m->group_chat_object;
|
||||
|
||||
if (length <= 1)
|
||||
return;
|
||||
|
||||
const uint8_t *invite_data = data + 1;
|
||||
uint16_t invite_length = length - 1;
|
||||
|
||||
switch (data[0]) {
|
||||
case INVITE_ID: {
|
||||
if (length != INVITE_PACKET_SIZE)
|
||||
return;
|
||||
|
||||
int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t));
|
||||
|
||||
if (groupnumber == -1) {
|
||||
g_c->invite_callback(m, friendnumber, invite_data, invite_length, g_c->invite_callback_userdata);
|
||||
return;
|
||||
} else {
|
||||
//TODO
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case INVITE_RESPONSE_ID: {
|
||||
if (length != INVITE_RESPONSE_PACKET_SIZE)
|
||||
return;
|
||||
|
||||
int groupnumber = get_group_num(g_c, data + 1 + sizeof(uint16_t));
|
||||
|
||||
if (groupnumber == -1) {
|
||||
return;
|
||||
} else {
|
||||
//TODO add_friend_to_groupchat(g_c, friendnumber, groupnumber, other_groupnum);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_friend_message_packet(Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Create new groupchat instance. */
|
||||
Group_Chats *new_groupchats(Messenger *m)
|
||||
{
|
||||
|
@ -313,6 +474,9 @@ Group_Chats *new_groupchats(Messenger *m)
|
|||
return NULL;
|
||||
|
||||
temp->m = m;
|
||||
m->group_chat_object = temp;
|
||||
m_callback_group_invite(m, &handle_friend_invite_packet);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
@ -326,6 +490,57 @@ void do_groupchats(Group_Chats *g_c)
|
|||
void kill_groupchats(Group_Chats *g_c)
|
||||
{
|
||||
//TODO
|
||||
g_c->m->group_chat_object = 0;
|
||||
free(g_c);
|
||||
}
|
||||
|
||||
/* Return the number of chats in the instance m.
|
||||
* You should use this to determine how much memory to allocate
|
||||
* for copy_chatlist. */
|
||||
/*
|
||||
uint32_t count_chatlist(const Messenger *m)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < m->numchats; i++) {
|
||||
if (m->chats[i]) {
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
/* Copy a list of valid chat IDs into the array out_list.
|
||||
* If out_list is NULL, returns 0.
|
||||
* Otherwise, returns the number of elements copied.
|
||||
* If the array was too small, the contents
|
||||
* of out_list will be truncated to list_size. */
|
||||
/*
|
||||
uint32_t copy_chatlist(const Messenger *m, int *out_list, uint32_t list_size)
|
||||
{
|
||||
if (!out_list)
|
||||
return 0;
|
||||
|
||||
if (m->numchats == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
uint32_t ret = 0;
|
||||
|
||||
for (i = 0; i < m->numchats; i++) {
|
||||
if (ret >= list_size) {
|
||||
break; *//* Abandon ship *//*
|
||||
}
|
||||
|
||||
if (m->chats[i]) {
|
||||
out_list[ret] = i;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
*/
|
|
@ -36,7 +36,7 @@ enum {
|
|||
GROUPCON_STATUS_NONE,
|
||||
GROUPCON_STATUS_VALID
|
||||
};
|
||||
/*
|
||||
|
||||
typedef struct {
|
||||
uint8_t client_id[crypto_box_PUBLICKEYBYTES];
|
||||
uint64_t pingid;
|
||||
|
@ -47,15 +47,16 @@ typedef struct {
|
|||
uint64_t last_recv_msgping;
|
||||
uint32_t last_message_number;
|
||||
|
||||
uint8_t nick[MAX_NICK_BYTES];
|
||||
uint8_t nick[MAX_NAME_LENGTH];
|
||||
uint16_t nick_len;
|
||||
|
||||
uint8_t deleted;
|
||||
uint64_t deleted_time;
|
||||
} Group_Peer;
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_GROUP_CONNECTIONS 4
|
||||
#define GROUP_IDENTIFIER_LENGTH crypto_box_KEYBYTES /* So we can use new_symmetric_key(...) to fill it */
|
||||
|
||||
typedef struct {
|
||||
uint8_t status;
|
||||
|
@ -67,6 +68,8 @@ typedef struct {
|
|||
uint8_t type;
|
||||
uint32_t number;
|
||||
} close[MAX_GROUP_CONNECTIONS];
|
||||
|
||||
uint8_t identifier[GROUP_IDENTIFIER_LENGTH];
|
||||
} Group_c;
|
||||
|
||||
typedef struct {
|
||||
|
@ -81,28 +84,35 @@ typedef struct {
|
|||
|
||||
Group_Connection *cons;
|
||||
uint32_t num_cons;
|
||||
|
||||
void (*invite_callback)(Messenger *m, int32_t, const uint8_t *, uint16_t, void *);
|
||||
void *invite_callback_userdata;
|
||||
void (*message_callback)(Messenger *m, int, int, const uint8_t *, uint16_t, void *);
|
||||
void *message_callback_userdata;
|
||||
} Group_Chats;
|
||||
|
||||
/* Set the callback for group invites.
|
||||
*
|
||||
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *group_public_key, void *userdata)
|
||||
* Function(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
|
||||
*
|
||||
* data of length is what needs to be passed to join_groupchat().
|
||||
*/
|
||||
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, void *),
|
||||
void *userdata);
|
||||
void g_callback_group_invite(Group_Chats *g_c, void (*function)(Messenger *m, int32_t, const uint8_t *, uint16_t,
|
||||
void *), void *userdata);
|
||||
|
||||
/* Set the callback for group messages.
|
||||
*
|
||||
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
|
||||
*/
|
||||
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
|
||||
void *userdata);
|
||||
void g_callback_group_message(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
|
||||
void *), void *userdata);
|
||||
|
||||
/* Set the callback for group actions.
|
||||
*
|
||||
* Function(Group_Chats *g_c, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata)
|
||||
*/
|
||||
void g_callback_group_action(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t, void *),
|
||||
void *userdata);
|
||||
void g_callback_group_action(Group_Chats *g_c, void (*function)(Messenger *m, int, int, const uint8_t *, uint16_t,
|
||||
void *), void *userdata);
|
||||
|
||||
/* Set callback function for peer name list changes.
|
||||
*
|
||||
|
@ -117,56 +127,56 @@ void g_callback_group_namelistchange(Group_Chats *g_c, void (*function)(Messenge
|
|||
* return group number on success.
|
||||
* return -1 on failure.
|
||||
*/
|
||||
int temp_c_add_groupchat(Group_Chats *g_c);
|
||||
int add_groupchat(Group_Chats *g_c);
|
||||
|
||||
/* Delete a groupchat from the chats array.
|
||||
*
|
||||
* return 0 on success.
|
||||
* return -1 if failure.
|
||||
*/
|
||||
int temp_c_del_groupchat(Group_Chats *g_c, int groupnumber);
|
||||
int del_groupchat(Group_Chats *g_c, int groupnumber);
|
||||
|
||||
/* Copy the name of peernumber who is in groupnumber to name.
|
||||
* name must be at least MAX_NICK_BYTES long.
|
||||
* name must be at least MAX_NAME_LENGTH long.
|
||||
*
|
||||
* return length of name if success
|
||||
* return -1 if failure
|
||||
*/
|
||||
int temp_c_m_group_peername(const Group_Chats *g_c, int groupnumber, int peernumber, uint8_t *name);
|
||||
int group_peername(const Group_Chats *g_c, int groupnumber, int peernumber, uint8_t *name);
|
||||
|
||||
/* invite friendnumber to groupnumber
|
||||
* return 0 on success
|
||||
* return -1 on failure
|
||||
*/
|
||||
int temp_c_invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber);
|
||||
int invite_friend(Group_Chats *g_c, int32_t friendnumber, int groupnumber);
|
||||
|
||||
/* Join a group (you need to have been invited first.)
|
||||
*
|
||||
* returns group number on success
|
||||
* returns -1 on failure.
|
||||
*/
|
||||
int temp_c_join_groupchat(Group_Chats *g_c, int32_t friendnumber, const uint8_t *friend_group_public_key);
|
||||
int join_groupchat(Group_Chats *g_c, int32_t friendnumber, uint8_t *data, uint16_t length);
|
||||
|
||||
/* send a group message
|
||||
* return 0 on success
|
||||
* return -1 on failure
|
||||
*/
|
||||
int temp_c_group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint32_t length);
|
||||
int group_message_send(const Group_Chats *g_c, int groupnumber, const uint8_t *message, uint32_t length);
|
||||
|
||||
/* send a group action
|
||||
* return 0 on success
|
||||
* return -1 on failure
|
||||
*/
|
||||
int temp_c_group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint32_t length);
|
||||
int group_action_send(const Group_Chats *g_c, int groupnumber, const uint8_t *action, uint32_t length);
|
||||
|
||||
/* Return the number of peers in the group chat on success.
|
||||
* return -1 on failure
|
||||
*/
|
||||
int temp_c_group_number_peers(const Group_Chats *g_c, int groupnumber);
|
||||
int group_number_peers(const Group_Chats *g_c, int groupnumber);
|
||||
|
||||
/* List all the peers in the group chat.
|
||||
*
|
||||
* Copies the names of the peers to the name[length][MAX_NICK_BYTES] array.
|
||||
* Copies the names of the peers to the name[length][MAX_NAME_LENGTH] array.
|
||||
*
|
||||
* Copies the lengths of the names to lengths[length]
|
||||
*
|
||||
|
@ -174,7 +184,7 @@ int temp_c_group_number_peers(const Group_Chats *g_c, int groupnumber);
|
|||
*
|
||||
* return -1 on failure.
|
||||
*/
|
||||
int temp_c_group_names(const Group_Chats *g_c, int groupnumber, uint8_t names[][MAX_NICK_BYTES], uint16_t lengths[],
|
||||
int group_names(const Group_Chats *g_c, int groupnumber, uint8_t names[][MAX_NAME_LENGTH], uint16_t lengths[],
|
||||
uint16_t length);
|
||||
|
||||
/* Create new groupchat instance. */
|
||||
|
|
|
@ -134,8 +134,7 @@ typedef int sock_t;
|
|||
#define TCP_INET6 (AF_INET6 + 3)
|
||||
#define TCP_FAMILY (AF_INET6 + 4)
|
||||
|
||||
typedef union
|
||||
{
|
||||
typedef union {
|
||||
uint8_t uint8[4];
|
||||
uint16_t uint16[2];
|
||||
uint32_t uint32;
|
||||
|
@ -143,8 +142,7 @@ typedef union
|
|||
}
|
||||
IP4;
|
||||
|
||||
typedef union
|
||||
{
|
||||
typedef union {
|
||||
uint8_t uint8[16];
|
||||
uint16_t uint16[8];
|
||||
uint32_t uint32[4];
|
||||
|
@ -153,8 +151,7 @@ typedef union
|
|||
}
|
||||
IP6;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t family;
|
||||
union {
|
||||
IP4 ip4;
|
||||
|
@ -163,8 +160,7 @@ typedef struct
|
|||
}
|
||||
IP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
IP ip;
|
||||
uint16_t port;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user