201 lines
4.8 KiB
C
201 lines
4.8 KiB
C
#include "laylink_kcp.h"
|
|
#include "ikcp.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct laylink_packet {
|
|
int len;
|
|
char* data;
|
|
struct laylink_packet* next;
|
|
} laylink_packet;
|
|
|
|
struct laylink_kcp {
|
|
ikcpcb* kcp;
|
|
laylink_packet* output_head;
|
|
laylink_packet* output_tail;
|
|
};
|
|
|
|
static void laylink_packet_free(laylink_packet* packet) {
|
|
if (packet == NULL) {
|
|
return;
|
|
}
|
|
free(packet->data);
|
|
free(packet);
|
|
}
|
|
|
|
static int laylink_kcp_output(const char* buffer, int len, ikcpcb* kcp, void* user) {
|
|
(void)kcp;
|
|
laylink_kcp* session = (laylink_kcp*)user;
|
|
if (session == NULL || len <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
laylink_packet* packet = (laylink_packet*)malloc(sizeof(laylink_packet));
|
|
if (packet == NULL) {
|
|
return -2;
|
|
}
|
|
|
|
packet->data = (char*)malloc((size_t)len);
|
|
if (packet->data == NULL) {
|
|
free(packet);
|
|
return -3;
|
|
}
|
|
|
|
memcpy(packet->data, buffer, (size_t)len);
|
|
packet->len = len;
|
|
packet->next = NULL;
|
|
|
|
if (session->output_tail != NULL) {
|
|
session->output_tail->next = packet;
|
|
} else {
|
|
session->output_head = packet;
|
|
}
|
|
session->output_tail = packet;
|
|
|
|
return 0;
|
|
}
|
|
|
|
laylink_kcp* laylink_kcp_create(unsigned int conv) {
|
|
laylink_kcp* session = (laylink_kcp*)calloc(1, sizeof(laylink_kcp));
|
|
if (session == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
session->kcp = ikcp_create(conv, session);
|
|
if (session->kcp == NULL) {
|
|
free(session);
|
|
return NULL;
|
|
}
|
|
|
|
session->kcp->output = laylink_kcp_output;
|
|
ikcp_nodelay(session->kcp, 1, 10, 2, 1);
|
|
ikcp_wndsize(session->kcp, 1024, 1024);
|
|
ikcp_setmtu(session->kcp, 1350);
|
|
|
|
return session;
|
|
}
|
|
|
|
void laylink_kcp_release(laylink_kcp* session) {
|
|
if (session == NULL) {
|
|
return;
|
|
}
|
|
|
|
laylink_packet* packet = session->output_head;
|
|
while (packet != NULL) {
|
|
laylink_packet* next = packet->next;
|
|
laylink_packet_free(packet);
|
|
packet = next;
|
|
}
|
|
|
|
if (session->kcp != NULL) {
|
|
ikcp_release(session->kcp);
|
|
}
|
|
free(session);
|
|
}
|
|
|
|
int laylink_kcp_nodelay(laylink_kcp* session, int nodelay, int interval, int resend, int nc) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_nodelay(session->kcp, nodelay, interval, resend, nc);
|
|
}
|
|
|
|
int laylink_kcp_wndsize(laylink_kcp* session, int sndwnd, int rcvwnd) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_wndsize(session->kcp, sndwnd, rcvwnd);
|
|
}
|
|
|
|
int laylink_kcp_setmtu(laylink_kcp* session, int mtu) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_setmtu(session->kcp, mtu);
|
|
}
|
|
|
|
int laylink_kcp_send(laylink_kcp* session, const char* buffer, int len) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_send(session->kcp, buffer, len);
|
|
}
|
|
|
|
int laylink_kcp_input(laylink_kcp* session, const char* buffer, long size) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_input(session->kcp, buffer, size);
|
|
}
|
|
|
|
void laylink_kcp_update(laylink_kcp* session, unsigned int current) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return;
|
|
}
|
|
ikcp_update(session->kcp, current);
|
|
}
|
|
|
|
unsigned int laylink_kcp_check(laylink_kcp* session, unsigned int current) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return current + 10;
|
|
}
|
|
return ikcp_check(session->kcp, current);
|
|
}
|
|
|
|
int laylink_kcp_peeksize(laylink_kcp* session) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_peeksize(session->kcp);
|
|
}
|
|
|
|
int laylink_kcp_recv(laylink_kcp* session, char* buffer, int len) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return -1;
|
|
}
|
|
return ikcp_recv(session->kcp, buffer, len);
|
|
}
|
|
|
|
void laylink_kcp_flush(laylink_kcp* session) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return;
|
|
}
|
|
ikcp_flush(session->kcp);
|
|
}
|
|
|
|
int laylink_kcp_waitsnd(laylink_kcp* session) {
|
|
if (session == NULL || session->kcp == NULL) {
|
|
return 0;
|
|
}
|
|
return ikcp_waitsnd(session->kcp);
|
|
}
|
|
|
|
int laylink_kcp_pending_output_size(laylink_kcp* session) {
|
|
if (session == NULL || session->output_head == NULL) {
|
|
return 0;
|
|
}
|
|
return session->output_head->len;
|
|
}
|
|
|
|
int laylink_kcp_pop_output(laylink_kcp* session, char* buffer, int len) {
|
|
if (session == NULL || session->output_head == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
laylink_packet* packet = session->output_head;
|
|
if (len < packet->len) {
|
|
return -packet->len;
|
|
}
|
|
|
|
memcpy(buffer, packet->data, (size_t)packet->len);
|
|
session->output_head = packet->next;
|
|
if (session->output_head == NULL) {
|
|
session->output_tail = NULL;
|
|
}
|
|
|
|
int packet_len = packet->len;
|
|
laylink_packet_free(packet);
|
|
return packet_len;
|
|
}
|