mirror of
https://github.com/fumiama/simple-dict.git
synced 2026-06-19 02:12:51 +08:00
add thread pool & optimize defines
This commit is contained in:
@@ -10,6 +10,31 @@ ELSE()
|
|||||||
add_definitions("-DCPUBIT32")
|
add_definitions("-DCPUBIT32")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
if($ENV{DICTKEYSZ})
|
||||||
|
message("custom dict key size: $ENV{DICTKEYSZ}")
|
||||||
|
add_definitions("-DDICTKEYSZ=$ENV{DICTKEYSZ}")
|
||||||
|
endif()
|
||||||
|
if($ENV{DICTDATSZ})
|
||||||
|
message("custom dict data size: $ENV{DICTDATSZ}")
|
||||||
|
add_definitions("-DDICTDATSZ=$ENV{DICTDATSZ}")
|
||||||
|
endif()
|
||||||
|
if($ENV{CRYPTO_SUMTABLE})
|
||||||
|
message("custom suntable: $ENV{CRYPTO_SUMTABLE}")
|
||||||
|
add_definitions("-DCRYPTO_SUMTABLE=$ENV{CRYPTO_SUMTABLE}")
|
||||||
|
endif()
|
||||||
|
if($ENV{THREADCNT})
|
||||||
|
message("custom suntable: $ENV{THREADCNT}")
|
||||||
|
add_definitions("-DTHREADCNT=$ENV{THREADCNT}")
|
||||||
|
endif()
|
||||||
|
if($ENV{MAXWAITSEC})
|
||||||
|
message("custom suntable: $ENV{MAXWAITSEC}")
|
||||||
|
add_definitions("-DMAXWAITSEC=$ENV{MAXWAITSEC}")
|
||||||
|
endif()
|
||||||
|
if($ENV{DICTPOOLBIT})
|
||||||
|
message("custom suntable: $ENV{DICTPOOLBIT}")
|
||||||
|
add_definitions("-DDICTPOOLBIT=$ENV{DICTPOOLBIT}")
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories("/usr/local/include")
|
include_directories("/usr/local/include")
|
||||||
link_directories("/usr/local/lib")
|
link_directories("/usr/local/lib")
|
||||||
|
|
||||||
@@ -32,4 +57,4 @@ target_link_libraries(cfgwriter libspb.a)
|
|||||||
|
|
||||||
INSTALL(TARGETS simple-dict-server RUNTIME DESTINATION bin)
|
INSTALL(TARGETS simple-dict-server RUNTIME DESTINATION bin)
|
||||||
#INSTALL(TARGETS simple-dict-client RUNTIME DESTINATION bin)
|
#INSTALL(TARGETS simple-dict-client RUNTIME DESTINATION bin)
|
||||||
#INSTALL(TARGETS cfgwriter RUNTIME DESTINATION bin)
|
#INSTALL(TARGETS cfgwriter RUNTIME DESTINATION bin)
|
||||||
|
|||||||
9
client.c
9
client.c
@@ -31,8 +31,6 @@ static uint32_t file_size;
|
|||||||
static int recv_bin = 0;
|
static int recv_bin = 0;
|
||||||
static config_t conf;
|
static config_t conf;
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
|
||||||
void getMessage(void *p) {
|
void getMessage(void *p) {
|
||||||
int c = 0, offset = 0;
|
int c = 0, offset = 0;
|
||||||
cmdpacket_t cp = (cmdpacket_t)bufr;
|
cmdpacket_t cp = (cmdpacket_t)bufr;
|
||||||
@@ -75,13 +73,14 @@ void getMessage(void *p) {
|
|||||||
//fwrite(data, datalen, 1, fp);
|
//fwrite(data, datalen, 1, fp);
|
||||||
//fclose(fp);
|
//fclose(fp);
|
||||||
off_t tmp = datalen;
|
off_t tmp = datalen;
|
||||||
char* newdata = raw_decrypt(data, &tmp, 0, conf.pwd);
|
char* ptr;
|
||||||
|
char* newdata = raw_decrypt(data, &tmp, 0, conf.pwd, &ptr);
|
||||||
if(newdata) {
|
if(newdata) {
|
||||||
printf("raw data len after decode: %d\n", (int)tmp);
|
printf("raw data len after decode: %d\n", (int)tmp);
|
||||||
FILE* fp = fopen(savepath, "wb+");
|
FILE* fp = fopen(savepath, "wb+");
|
||||||
fwrite(newdata, (size_t)tmp, 1, fp);
|
fwrite(newdata, (size_t)tmp, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
free(newdata);
|
free(ptr);
|
||||||
puts("recv raw data succeed.");
|
puts("recv raw data succeed.");
|
||||||
} else puts("decode raw data error.");
|
} else puts("decode raw data error.");
|
||||||
} else puts("recv raw data error.");
|
} else puts("recv raw data error.");
|
||||||
@@ -110,7 +109,7 @@ void getMessage(void *p) {
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("[handle] Decrypt %d bytes data...\n", (int)cp->datalen);
|
printf("[handle] Decrypt %d bytes data...\n", (int)cp->datalen);
|
||||||
#endif
|
#endif
|
||||||
if(cmdpacket_decrypt(cp, 0, conf.pwd)) {
|
if(!cmdpacket_decrypt(cp, 0, conf.pwd)) {
|
||||||
cp->data[cp->datalen] = 0;
|
cp->data[cp->datalen] = 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("[normal] Get %u bytes packet with data: %s\n", offset, cp->data);
|
printf("[normal] Get %u bytes packet with data: %s\n", offset, cp->data);
|
||||||
|
|||||||
2
config.h
2
config.h
@@ -7,4 +7,4 @@ struct config_t {
|
|||||||
};
|
};
|
||||||
typedef struct config_t config_t;
|
typedef struct config_t config_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
163
crypto.h
163
crypto.h
@@ -11,25 +11,29 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
|
#ifndef CRYPTO_SUMTABLE
|
||||||
|
#define CRYPTO_SUMTABLE {\
|
||||||
|
0x9e3579b9,\
|
||||||
|
0x3c6ef172,\
|
||||||
|
0xd2a66d2b,\
|
||||||
|
0x78dd36e4,\
|
||||||
|
0x17e5609d,\
|
||||||
|
0xb54fda56,\
|
||||||
|
0x5384560f,\
|
||||||
|
0xf1bb77c8,\
|
||||||
|
0x8ff24781,\
|
||||||
|
0x2e4ac13a,\
|
||||||
|
0xcc653af3,\
|
||||||
|
0x6a9964ac,\
|
||||||
|
0x08d12965,\
|
||||||
|
0xa708081e,\
|
||||||
|
0x451221d7,\
|
||||||
|
0xe37793d0 \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// TEA encoding sumtable
|
// TEA encoding sumtable
|
||||||
static const uint32_t sumtable[0x10] = {
|
static const uint32_t sumtable[0x10] = CRYPTO_SUMTABLE;
|
||||||
0x9e3579b9,
|
|
||||||
0x3c6ef172,
|
|
||||||
0xd2a66d2b,
|
|
||||||
0x78dd36e4,
|
|
||||||
0x17e5609d,
|
|
||||||
0xb54fda56,
|
|
||||||
0x5384560f,
|
|
||||||
0xf1bb77c8,
|
|
||||||
0x8ff24781,
|
|
||||||
0x2e4ac13a,
|
|
||||||
0xcc653af3,
|
|
||||||
0x6a9964ac,
|
|
||||||
0x08d12965,
|
|
||||||
0xa708081e,
|
|
||||||
0x451221d7,
|
|
||||||
0xe37793d0,
|
|
||||||
};
|
|
||||||
|
|
||||||
static uint8_t seqs[THREADCNT]; // 消息序号
|
static uint8_t seqs[THREADCNT]; // 消息序号
|
||||||
|
|
||||||
@@ -54,66 +58,64 @@ static void reset_seq(int index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char* raw_encrypt(const char* buf, off_t* len, int index, const char pwd[64]) {
|
static char* raw_encrypt(const char* buf, off_t* len, int index, const char pwd[64]) {
|
||||||
TEADAT tin = {*len, (uint8_t*)buf};
|
TEA tea;
|
||||||
TEADAT tout;
|
|
||||||
TEA tea[4];
|
|
||||||
|
|
||||||
((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0];
|
((uint64_t*)tea.t)[0] = ((uint64_t*)pwd)[0];
|
||||||
((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1];
|
((uint64_t*)tea.t)[1] = ((uint64_t*)pwd)[1];
|
||||||
((uint8_t*)tea)[15] = seqs[index]++;
|
((uint8_t*)tea.t)[15] = seqs[index]++;
|
||||||
tea_encrypt_native_endian(tea, sumtable, &tin, &tout);
|
|
||||||
|
|
||||||
*len = tout.len;
|
|
||||||
char* encbuf = (char*)malloc(*len);
|
|
||||||
memcpy(encbuf, tout.data, *len);
|
|
||||||
free(tout.ptr);
|
|
||||||
|
|
||||||
|
int64_t dstlen = tea_encrypt_len(*len);
|
||||||
|
char* encbuf = (char*)malloc(dstlen);
|
||||||
|
if(!encbuf) return NULL;
|
||||||
|
*len = tea_encrypt_native_endian(tea, sumtable, (const uint8_t*)buf, *len, (uint8_t*)encbuf);
|
||||||
return encbuf;
|
return encbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* raw_decrypt(const char* buf, off_t* len, int index, const char pwd[64]) {
|
// raw_decrypt buf: in->src out->dstptr
|
||||||
TEADAT tin = {*len, (uint8_t*)buf};
|
static char* raw_decrypt(const char* buf, off_t* len, int index, const char pwd[64], char** ptr) {
|
||||||
TEADAT tout;
|
TEA tea;
|
||||||
TEA tea[4];
|
|
||||||
|
|
||||||
((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0];
|
((uint64_t*)tea.t)[0] = ((uint64_t*)pwd)[0];
|
||||||
((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1];
|
((uint64_t*)tea.t)[1] = ((uint64_t*)pwd)[1];
|
||||||
((uint8_t*)tea)[15] = seqs[index];
|
((uint8_t*)tea.t)[15] = seqs[index];
|
||||||
if(!tea_decrypt_native_endian(tea, sumtable, &tin, &tout)) return NULL;
|
|
||||||
else if(tout.len <= 0) {
|
|
||||||
free(tout.ptr);
|
|
||||||
return NULL;
|
|
||||||
} else seqs[index]++;
|
|
||||||
|
|
||||||
*len = tout.len;
|
|
||||||
char* decbuf = (char*)malloc(*len);
|
char* decbuf = (char*)malloc(*len);
|
||||||
memcpy(decbuf, tout.data, *len);
|
if(!decbuf) return NULL;
|
||||||
free(tout.ptr);
|
char* out = (char*)tea_decrypt_native_endian(tea, sumtable, (const uint8_t*)buf, *len, (uint8_t*)decbuf);
|
||||||
|
if(!out) {
|
||||||
|
free(decbuf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return decbuf;
|
seqs[index]++;
|
||||||
|
|
||||||
|
*len = tea_decrypt_len(*len, decbuf[0]);
|
||||||
|
*ptr = decbuf;
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmdpacket_encrypt(cmdpacket_t p, int index, const char pwd[64], const char* data) {
|
static int cmdpacket_encrypt(cmdpacket_t p, int index, const char pwd[64], const char* data) {
|
||||||
TEADAT tin = {p->datalen, (uint8_t *)data};
|
TEA tea;
|
||||||
TEADAT tout;
|
|
||||||
TEA tea[4];
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("encrypt len: %d, data: ", p->datalen);
|
printf("encrypt len: %d, data: ", p->datalen);
|
||||||
for(int i = 0; i < p->datalen; i++) printf("%02x", data[i]);
|
for(int i = 0; i < p->datalen; i++) printf("%02x", data[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0];
|
((uint64_t*)tea.t)[0] = ((uint64_t*)pwd)[0];
|
||||||
((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1];
|
((uint64_t*)tea.t)[1] = ((uint64_t*)pwd)[1];
|
||||||
((uint8_t*)tea)[15] = seqs[index]++;
|
((uint8_t*)tea.t)[15] = seqs[index]++;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("encrypt tea: ");
|
printf("encrypt tea: ");
|
||||||
for(int i = 0; i < 16; i++) printf("%02x", ((uint8_t*)tea)[i]);
|
for(int i = 0; i < 16; i++) printf("%02x", ((uint8_t*)tea.t)[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tea_encrypt_native_endian(tea, sumtable, &tin, &tout);
|
int64_t outlen = tea_encrypt_len(p->datalen);
|
||||||
|
|
||||||
|
char out[outlen];
|
||||||
|
|
||||||
md5((const uint8_t *)data, p->datalen, p->md5);
|
md5((const uint8_t *)data, p->datalen, p->md5);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -122,63 +124,62 @@ static void cmdpacket_encrypt(cmdpacket_t p, int index, const char pwd[64], cons
|
|||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
p->datalen = tout.len;
|
p->datalen = tea_encrypt_native_endian(tea, sumtable, (const uint8_t*)data, p->datalen, (uint8_t*)out);
|
||||||
memcpy(p->data, tout.data, p->datalen);
|
memcpy(p->data, out, p->datalen);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("encrypted data len: %d, data: ", p->datalen);
|
printf("encrypted data len: %d, data: ", p->datalen);
|
||||||
for(int i = 0; i < p->datalen; i++) printf("%02x", p->data[i]);
|
for(int i = 0; i < p->datalen; i++) printf("%02x", p->data[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
free(tout.ptr);
|
|
||||||
|
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmdpacket_decrypt(cmdpacket_t p, int index, const char pwd[64]) {
|
static int cmdpacket_decrypt(cmdpacket_t p, int index, const char pwd[64]) {
|
||||||
TEADAT tin = {p->datalen, p->data};
|
TEA tea;
|
||||||
TEADAT tout;
|
|
||||||
TEA tea[4];
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("decrypt len: %d, data: ", p->datalen);
|
printf("decrypt len: %d, data: ", p->datalen);
|
||||||
for(int i = 0; i < p->datalen; i++) printf("%02x", p->data[i]);
|
for(int i = 0; i < p->datalen; i++) printf("%02x", p->data[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
((uint64_t*)tea)[0] = ((uint64_t*)pwd)[0];
|
((uint64_t*)tea.t)[0] = ((uint64_t*)pwd)[0];
|
||||||
((uint64_t*)tea)[1] = ((uint64_t*)pwd)[1];
|
((uint64_t*)tea.t)[1] = ((uint64_t*)pwd)[1];
|
||||||
((uint8_t*)tea)[15] = seqs[index];
|
((uint8_t*)tea.t)[15] = seqs[index];
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("decrypt tea: ");
|
printf("decrypt tea: ");
|
||||||
for(int i = 0; i < 16; i++) printf("%02x", ((uint8_t*)tea)[i]);
|
for(int i = 0; i < 16; i++) printf("%02x", ((uint8_t*)tea.t)[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!tea_decrypt_native_endian(tea, sumtable, &tin, &tout)) return 0;
|
char outbuf[p->datalen];
|
||||||
if(tout.len <= 0) {
|
|
||||||
free(tout.ptr);
|
char* out = (char*)tea_decrypt_native_endian(tea, sumtable, (const uint8_t*)p->data, p->datalen, (uint8_t*)outbuf);
|
||||||
return 0;
|
if(!out) return 2;
|
||||||
}
|
|
||||||
|
p->datalen = tea_decrypt_len(p->datalen, outbuf[0]);
|
||||||
|
|
||||||
uint8_t datamd5[16];
|
uint8_t datamd5[16];
|
||||||
md5(tout.data, tout.len, datamd5);
|
md5((const uint8_t*)out, p->datalen, datamd5);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("decrypt md5: ");
|
printf("decrypt md5: ");
|
||||||
for(int i = 0; i < 16; i++) printf("%02x", datamd5[i]);
|
for(int i = 0; i < 16; i++) printf("%02x", datamd5[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
printf("decrypted data len: %u, data: ", (unsigned int)tout.len);
|
printf("decrypted data len: %u, data: ", (unsigned int)p->datalen);
|
||||||
for(int i = 0; i < tout.len; i++) printf("%02x", tout.data[i]);
|
for(int i = 0; i < p->datalen; i++) printf("%02x", out[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(is_md5_equal((uint8_t*)datamd5, p->md5)) {
|
if(is_md5_equal((uint8_t*)datamd5, p->md5)) {
|
||||||
seqs[index]++;
|
seqs[index]++;
|
||||||
p->datalen = tout.len;
|
memcpy(p->data, out, p->datalen);
|
||||||
memcpy(p->data, tout.data, p->datalen);
|
return 0;
|
||||||
free(tout.ptr);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
free(tout.ptr);
|
|
||||||
return 0;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* _CRYPTO_H_ */
|
#endif /* _CRYPTO_H_ */
|
||||||
|
|||||||
11
dict.h
11
dict.h
@@ -11,8 +11,13 @@
|
|||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
#define DICTKEYSZ 127
|
#ifndef DICTKEYSZ
|
||||||
#define DICTDATSZ 127
|
#define DICTKEYSZ 127
|
||||||
|
#endif
|
||||||
|
#ifndef DICTDATSZ
|
||||||
|
#define DICTDATSZ 127
|
||||||
|
#endif
|
||||||
|
|
||||||
struct dict_t {
|
struct dict_t {
|
||||||
char key[DICTKEYSZ];
|
char key[DICTKEYSZ];
|
||||||
char data[DICTDATSZ];
|
char data[DICTDATSZ];
|
||||||
@@ -145,4 +150,4 @@ static inline int is_dict_md5_equal(uint8_t* digest) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ struct DICTBLK{
|
|||||||
typedef struct DICTBLK DICTBLK;
|
typedef struct DICTBLK DICTBLK;
|
||||||
#define DICTBLKSZ sizeof(DICTBLK)
|
#define DICTBLKSZ sizeof(DICTBLK)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
256
server.c
256
server.c
@@ -5,6 +5,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <simple_protobuf.h>
|
#include <simple_protobuf.h>
|
||||||
|
#include <simplecrypto.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -38,7 +39,11 @@ struct thread_timer_t {
|
|||||||
ssize_t numbytes;
|
ssize_t numbytes;
|
||||||
char *dat;
|
char *dat;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
uint8_t buf[BUFSIZ-sizeof(uint32_t)-sizeof(int)-sizeof(time_t)-sizeof(ssize_t)-sizeof(char*)-sizeof(pthread_t)];
|
pthread_cond_t c;
|
||||||
|
pthread_mutex_t mc;
|
||||||
|
pthread_rwlock_t mb;
|
||||||
|
uint8_t isbusy;
|
||||||
|
uint8_t buf[CMDPACKET_LEN_MAX];
|
||||||
};
|
};
|
||||||
typedef struct thread_timer_t thread_timer_t;
|
typedef struct thread_timer_t thread_timer_t;
|
||||||
static thread_timer_t timers[THREADCNT];
|
static thread_timer_t timers[THREADCNT];
|
||||||
@@ -123,20 +128,23 @@ static inline uint32_t last_nonnull(const char* p, uint32_t max_size) {
|
|||||||
|
|
||||||
static int send_data(int accept_fd, int index, server_ack_t cmd, const char *data, size_t length) {
|
static int send_data(int accept_fd, int index, server_ack_t cmd, const char *data, size_t length) {
|
||||||
char buf[CMDPACKET_LEN_MAX];
|
char buf[CMDPACKET_LEN_MAX];
|
||||||
cmdpacket_t p = (cmdpacket_t)buf;
|
if(length <= UINT8_MAX) {
|
||||||
p->cmd = (uint8_t)cmd;
|
cmdpacket_t p = (cmdpacket_t)buf;
|
||||||
p->datalen = length;
|
p->cmd = (uint8_t)cmd;
|
||||||
cmdpacket_encrypt(p, index, cfg.pwd, data);
|
p->datalen = length;
|
||||||
int total = CMDPACKET_HEAD_LEN+p->datalen;
|
cmdpacket_encrypt(p, index, cfg.pwd, data);
|
||||||
if(!~send(accept_fd, buf, total, 0)) {
|
int total = CMDPACKET_HEAD_LEN+p->datalen;
|
||||||
perror("Send data error");
|
if(!~send(accept_fd, buf, total, 0)) {
|
||||||
return 0;
|
perror("Send data error");
|
||||||
} else {
|
return 0;
|
||||||
|
}
|
||||||
printf("Send %d bytes data: ", total);
|
printf("Send %d bytes data: ", total);
|
||||||
for(int i = 0; i < length; i++) putchar(data[i]);
|
for(int i = 0; i < length; i++) putchar(data[i]);
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
fputs("Send data: length too long.", stderr);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_all(thread_timer_t *timer) {
|
static int send_all(thread_timer_t *timer) {
|
||||||
@@ -565,6 +573,10 @@ static void accept_timer(void *p) {
|
|||||||
|
|
||||||
sleep(MAXWAITSEC / 4);
|
sleep(MAXWAITSEC / 4);
|
||||||
while(timer->thread && !pthread_kill(timer->thread, 0)) {
|
while(timer->thread && !pthread_kill(timer->thread, 0)) {
|
||||||
|
pthread_rwlock_rdlock(&timer->mb);
|
||||||
|
uint8_t isbusy = timer->isbusy;
|
||||||
|
pthread_rwlock_unlock(&timer->mb);
|
||||||
|
if(!isbusy) break;
|
||||||
if(is_dict_opening) touch_timer(p);
|
if(is_dict_opening) touch_timer(p);
|
||||||
time_t waitsec = time(NULL) - timer->touch;
|
time_t waitsec = time(NULL) - timer->touch;
|
||||||
printf("Wait sec: %u, max: %u\n", (unsigned int)waitsec, MAXWAITSEC);
|
printf("Wait sec: %u, max: %u\n", (unsigned int)waitsec, MAXWAITSEC);
|
||||||
@@ -593,12 +605,19 @@ static void cleanup_thread(thread_timer_t* timer) {
|
|||||||
}
|
}
|
||||||
close_dict(timer->index);
|
close_dict(timer->index);
|
||||||
timer->thread = 0;
|
timer->thread = 0;
|
||||||
|
timer->isbusy = 0;
|
||||||
|
pthread_cond_destroy(&timer->c);
|
||||||
|
pthread_mutex_destroy(&timer->mc);
|
||||||
|
pthread_rwlock_destroy(&timer->mb);
|
||||||
setdicts[timer->index].data[0] = 0;
|
setdicts[timer->index].data[0] = 0;
|
||||||
puts("Finish cleaning");
|
puts("Finish cleaning");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_int(int signo) {
|
static void handle_int(int signo) {
|
||||||
puts("Keyboard interrupted");
|
puts("Keyboard interrupted");
|
||||||
|
for(int i = 0; i < THREADCNT; i++) {
|
||||||
|
if(timers[i].thread) pthread_kill(timers[i].thread, SIGQUIT);
|
||||||
|
}
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,108 +627,125 @@ static void handle_pipe(int signo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void handle_accept(void *p) {
|
static void handle_accept(void *p) {
|
||||||
puts("Handling accept...");
|
pthread_cond_init(&timer_pointer_of(p)->c, NULL);
|
||||||
pthread_t thread;
|
pthread_mutex_init(&timer_pointer_of(p)->mc, NULL);
|
||||||
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) {
|
pthread_rwlock_init(&timer_pointer_of(p)->mb, NULL);
|
||||||
perror("Error creating timer thread");
|
|
||||||
cleanup_thread(timer_pointer_of(p));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
puts("Creating timer thread succeeded");
|
|
||||||
pthread_cleanup_push((void*)&cleanup_thread, p);
|
pthread_cleanup_push((void*)&cleanup_thread, p);
|
||||||
int accept_fd = timer_pointer_of(p)->accept_fd;
|
while(1) {
|
||||||
uint32_t index = timer_pointer_of(p)->index;
|
puts("Handling accept...");
|
||||||
uint8_t *buff = timer_pointer_of(p)->buf;
|
pthread_t thread;
|
||||||
cmdpacket_t cp = (cmdpacket_t)buff;
|
pthread_rwlock_unlock(&timer_pointer_of(p)->mb);
|
||||||
ssize_t numbytes = 0, offset = 0;
|
pthread_rwlock_wrlock(&timer_pointer_of(p)->mb);
|
||||||
while(
|
timer_pointer_of(p)->isbusy = 1;
|
||||||
offset >= CMDPACKET_HEAD_LEN
|
pthread_rwlock_unlock(&timer_pointer_of(p)->mb);
|
||||||
|| (numbytes = recv(accept_fd, buff+offset, CMDPACKET_HEAD_LEN-offset, MSG_WAITALL)) > 0
|
if (pthread_create(&thread, &attr, (void *)&accept_timer, p)) {
|
||||||
) {
|
perror("Error creating timer thread");
|
||||||
touch_timer(p);
|
//cleanup_thread(timer_pointer_of(p));
|
||||||
offset += numbytes;
|
pthread_rwlock_unlock(&timer_pointer_of(p)->mb);
|
||||||
#ifdef DEBUG
|
return;
|
||||||
printf("[handle] Get %zd bytes, total: %zd.\n", numbytes, offset);
|
|
||||||
#endif
|
|
||||||
if(offset < CMDPACKET_HEAD_LEN) break;
|
|
||||||
if(offset < CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen)) {
|
|
||||||
ssize_t toread = CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen)-offset;
|
|
||||||
numbytes = recv(accept_fd, buff+offset, toread, MSG_WAITALL);
|
|
||||||
if(numbytes != toread) break;
|
|
||||||
else {
|
|
||||||
offset += numbytes;
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("[handle] Get %zd bytes, total: %zd.\n", numbytes, offset);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
numbytes = CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen); // 暂存 packet len
|
puts("Creating timer thread succeeded");
|
||||||
if(offset < numbytes) break;
|
int accept_fd = timer_pointer_of(p)->accept_fd;
|
||||||
#ifdef DEBUG
|
uint32_t index = timer_pointer_of(p)->index;
|
||||||
printf("[handle] Decrypt %d bytes data...\n", (int)cp->datalen);
|
uint8_t *buff = timer_pointer_of(p)->buf;
|
||||||
#endif
|
cmdpacket_t cp = (cmdpacket_t)buff;
|
||||||
if(cp->cmd <= CMDEND) {
|
ssize_t numbytes = 0, offset = 0;
|
||||||
if(cmdpacket_decrypt(cp, index, cfg.pwd)) {
|
while(
|
||||||
cp->data[cp->datalen] = 0;
|
offset >= CMDPACKET_HEAD_LEN
|
||||||
timer_pointer_of(p)->dat = (char*)cp->data;
|
|| (numbytes = recv(accept_fd, buff+offset, CMDPACKET_HEAD_LEN-offset, MSG_WAITALL)) > 0
|
||||||
timer_pointer_of(p)->numbytes = (ssize_t)(cp->datalen);
|
) {
|
||||||
printf("[normal] Get %zd bytes packet with cmd: %d, data: %s\n", offset, cp->cmd, cp->data);
|
touch_timer(p);
|
||||||
switch(cp->cmd) {
|
offset += numbytes;
|
||||||
case CMDGET:
|
#ifdef DEBUG
|
||||||
if(!has_dict_opened && !s1_get(timer_pointer_of(p))) goto CONV_END;
|
printf("[handle] Get %zd bytes, total: %zd.\n", numbytes, offset);
|
||||||
|
#endif
|
||||||
|
if(offset < CMDPACKET_HEAD_LEN) break;
|
||||||
|
if(offset < CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen)) {
|
||||||
|
ssize_t toread = CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen)-offset;
|
||||||
|
numbytes = recv(accept_fd, buff+offset, toread, MSG_WAITALL);
|
||||||
|
if(numbytes != toread) break;
|
||||||
|
else {
|
||||||
|
offset += numbytes;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[handle] Get %zd bytes, total: %zd.\n", numbytes, offset);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
numbytes = CMDPACKET_HEAD_LEN+(ssize_t)(cp->datalen); // 暂存 packet len
|
||||||
|
if(offset < numbytes) break;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[handle] Decrypt %d bytes data...\n", (int)cp->datalen);
|
||||||
|
#endif
|
||||||
|
if(cp->cmd <= CMDEND) {
|
||||||
|
if(!cmdpacket_decrypt(cp, index, cfg.pwd)) {
|
||||||
|
cp->data[cp->datalen] = 0;
|
||||||
|
timer_pointer_of(p)->dat = (char*)cp->data;
|
||||||
|
timer_pointer_of(p)->numbytes = (ssize_t)(cp->datalen);
|
||||||
|
printf("[normal] Get %zd bytes packet with cmd: %d, data: %s\n", offset, cp->cmd, cp->data);
|
||||||
|
switch(cp->cmd) {
|
||||||
|
case CMDGET:
|
||||||
|
if(!has_dict_opened && !s1_get(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
case CMDCAT:
|
||||||
|
if(!has_dict_opened && !send_all(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
case CMDMD5:
|
||||||
|
if(!has_dict_opened && !s5_md5(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
case CMDACK:
|
||||||
|
case CMDEND:
|
||||||
|
default: goto CONV_END; break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts("Decrypt normal data failed");
|
||||||
break;
|
break;
|
||||||
case CMDCAT:
|
}
|
||||||
if(!has_dict_opened && !send_all(timer_pointer_of(p))) goto CONV_END;
|
} else if(cp->cmd <= CMDDAT) {
|
||||||
|
if(!cmdpacket_decrypt(cp, index, cfg.sps)) {
|
||||||
|
cp->data[cp->datalen] = 0;
|
||||||
|
timer_pointer_of(p)->dat = (char*)cp->data;
|
||||||
|
timer_pointer_of(p)->numbytes = (ssize_t)(cp->datalen);
|
||||||
|
printf("[super] Get %zd bytes packet with data: %s\n", offset, cp->data);
|
||||||
|
switch(cp->cmd) {
|
||||||
|
case CMDSET:
|
||||||
|
if(!has_dict_opened && !s2_set(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
case CMDDEL:
|
||||||
|
if(!has_dict_opened && !s4_del(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
case CMDDAT:
|
||||||
|
if(!has_dict_opened && !s3_set_data(timer_pointer_of(p))) goto CONV_END;
|
||||||
|
break;
|
||||||
|
default: goto CONV_END; break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puts("Decrypt super data failed");
|
||||||
break;
|
break;
|
||||||
case CMDMD5:
|
|
||||||
if(!has_dict_opened && !s5_md5(timer_pointer_of(p))) goto CONV_END;
|
|
||||||
break;
|
|
||||||
case CMDACK:
|
|
||||||
case CMDEND:
|
|
||||||
default: goto CONV_END; break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
puts("Decrypt normal data failed");
|
puts("Invalid command");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if(cp->cmd <= CMDDAT) {
|
if(offset > numbytes) {
|
||||||
if(cmdpacket_decrypt(cp, index, cfg.sps)) {
|
offset -= numbytes;
|
||||||
cp->data[cp->datalen] = 0;
|
memmove(buff, buff+numbytes, offset);
|
||||||
timer_pointer_of(p)->dat = (char*)cp->data;
|
numbytes = 0;
|
||||||
timer_pointer_of(p)->numbytes = (ssize_t)(cp->datalen);
|
} else offset = 0;
|
||||||
printf("[super] Get %zd bytes packet with data: %s\n", offset, cp->data);
|
#ifdef DEBUG
|
||||||
switch(cp->cmd) {
|
printf("Offset after analyzing packet: %zd\n", offset);
|
||||||
case CMDSET:
|
#endif
|
||||||
if(!has_dict_opened && !s2_set(timer_pointer_of(p))) goto CONV_END;
|
|
||||||
break;
|
|
||||||
case CMDDEL:
|
|
||||||
if(!has_dict_opened && !s4_del(timer_pointer_of(p))) goto CONV_END;
|
|
||||||
break;
|
|
||||||
case CMDDAT:
|
|
||||||
if(!has_dict_opened && !s3_set_data(timer_pointer_of(p))) goto CONV_END;
|
|
||||||
break;
|
|
||||||
default: goto CONV_END; break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
puts("Decrypt super data failed");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
puts("Invalid command");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if(offset > numbytes) {
|
CONV_END: puts("Conversation end");
|
||||||
offset -= numbytes;
|
puts("Thread job finished normally");
|
||||||
memmove(buff, buff+numbytes, offset);
|
pthread_rwlock_wrlock(&timer_pointer_of(p)->mb);
|
||||||
numbytes = 0;
|
timer_pointer_of(p)->isbusy = 0;
|
||||||
} else offset = 0;
|
pthread_mutex_lock(&timer_pointer_of(p)->mc);
|
||||||
#ifdef DEBUG
|
pthread_rwlock_unlock(&timer_pointer_of(p)->mb);
|
||||||
printf("Offset after analyzing packet: %zd\n", offset);
|
pthread_cond_wait(&timer_pointer_of(p)->c, &timer_pointer_of(p)->mc);
|
||||||
#endif
|
pthread_mutex_unlock(&timer_pointer_of(p)->mc);
|
||||||
|
puts("Thread wakeup");
|
||||||
}
|
}
|
||||||
CONV_END: puts("Conversation end");
|
|
||||||
pthread_cleanup_pop(1);
|
pthread_cleanup_pop(1);
|
||||||
puts("Thread exited normally");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void accept_client(int fd) {
|
static void accept_client(int fd) {
|
||||||
@@ -737,7 +773,12 @@ static void accept_client(int fd) {
|
|||||||
while(1) {
|
while(1) {
|
||||||
puts("Ready for accept, waitting...");
|
puts("Ready for accept, waitting...");
|
||||||
int p = 0;
|
int p = 0;
|
||||||
while(p < THREADCNT && timers[p].thread) p++;
|
while(p < THREADCNT) {
|
||||||
|
pthread_rwlock_rdlock(&timers[p].mb);
|
||||||
|
if(!timers[p].isbusy) break;
|
||||||
|
pthread_rwlock_unlock(&timers[p].mb);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
if(p >= THREADCNT) {
|
if(p >= THREADCNT) {
|
||||||
puts("Max thread cnt exceeded");
|
puts("Max thread cnt exceeded");
|
||||||
sleep(1);
|
sleep(1);
|
||||||
@@ -769,12 +810,17 @@ static void accept_client(int fd) {
|
|||||||
timer->index = p;
|
timer->index = p;
|
||||||
timer->touch = time(NULL);
|
timer->touch = time(NULL);
|
||||||
reset_seq(p);
|
reset_seq(p);
|
||||||
if (pthread_create(&timer->thread, &attr, (void *)&handle_accept, timer)) {
|
if(timer->thread) {
|
||||||
|
pthread_mutex_lock(&timer->mc);
|
||||||
|
pthread_cond_signal(&timer->c); // wakeup thread
|
||||||
|
pthread_mutex_unlock(&timer->mc);
|
||||||
|
puts("Pick thread from pool");
|
||||||
|
} else if (pthread_create(&timer->thread, &attr, (void *)&handle_accept, timer)) {
|
||||||
perror("Error creating thread");
|
perror("Error creating thread");
|
||||||
cleanup_thread(timer);
|
cleanup_thread(timer);
|
||||||
|
pthread_rwlock_unlock(&timer->mb);
|
||||||
continue;
|
continue;
|
||||||
}
|
} else puts("Creating thread succeeded");
|
||||||
puts("Creating thread succeeded");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
server.h
17
server.h
@@ -3,11 +3,16 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define THREADCNT 32
|
#ifndef THREADCNT
|
||||||
#define MAXWAITSEC 8
|
#define THREADCNT 32
|
||||||
|
#endif
|
||||||
|
#ifndef MAXWAITSEC
|
||||||
|
#define MAXWAITSEC 8
|
||||||
|
#endif
|
||||||
|
#ifndef DICTPOOLBIT
|
||||||
// DICTPOOLBIT must be lower than 4*8 = 32
|
// DICTPOOLBIT must be lower than 4*8 = 32
|
||||||
#define DICTPOOLBIT 16
|
#define DICTPOOLBIT 16
|
||||||
|
#endif
|
||||||
|
|
||||||
enum server_cmd_t {CMDGET, CMDCAT, CMDMD5, CMDACK, CMDEND, CMDSET, CMDDEL, CMDDAT};
|
enum server_cmd_t {CMDGET, CMDCAT, CMDMD5, CMDACK, CMDEND, CMDSET, CMDDEL, CMDDAT};
|
||||||
enum server_ack_t {ACKNONE=0b0000011, ACKSUCC=0b0010011, ACKDATA=0b0100011, ACKNULL=0b0110011, ACKNEQU=0b1000011, ACKERRO=0b1010011};
|
enum server_ack_t {ACKNONE=0b0000011, ACKSUCC=0b0010011, ACKDATA=0b0100011, ACKNULL=0b0110011, ACKNEQU=0b1000011, ACKERRO=0b1010011};
|
||||||
@@ -16,7 +21,7 @@ typedef enum server_cmd_t server_cmd_t;
|
|||||||
typedef enum server_ack_t server_ack_t;
|
typedef enum server_ack_t server_ack_t;
|
||||||
|
|
||||||
struct cmdpacket_t {
|
struct cmdpacket_t {
|
||||||
uint8_t cmd; // SERVERCMD or SERVERACK
|
uint8_t cmd; // high 1bit: undefined; low 7 bits: SERVERCMD or SERVERACK
|
||||||
uint8_t datalen; // data len is less than 255
|
uint8_t datalen; // data len is less than 255
|
||||||
uint8_t md5[16]; // md5 digest of data below
|
uint8_t md5[16]; // md5 digest of data below
|
||||||
uint8_t data[]; // with TEA encoding, 64 bytes will be 160 bytes
|
uint8_t data[]; // with TEA encoding, 64 bytes will be 160 bytes
|
||||||
@@ -24,6 +29,6 @@ struct cmdpacket_t {
|
|||||||
typedef struct cmdpacket_t* cmdpacket_t;
|
typedef struct cmdpacket_t* cmdpacket_t;
|
||||||
|
|
||||||
#define CMDPACKET_HEAD_LEN (1+1+16)
|
#define CMDPACKET_HEAD_LEN (1+1+16)
|
||||||
#define CMDPACKET_LEN_MAX (CMDPACKET_HEAD_LEN+255)
|
#define CMDPACKET_LEN_MAX (CMDPACKET_HEAD_LEN+UINT8_MAX)
|
||||||
|
|
||||||
#endif /* _SERVER_H_ */
|
#endif /* _SERVER_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user