getty.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483
  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <unistd.h>
  4. #include <stdbool.h>
  5. #include <stdlib.h>
  6. #include <fcntl.h>
  7. #include <sys/stat.h>
  8. #include <sys/types.h>
  9. #include <string.h>
  10. #include <spawn.h>
  11. #include <sys/wait.h>
  12. #include <signal.h>
  13. #include <pty.h>
  14. #include <termios.h>
  15. #include <sys/ioctl.h>
  16. #define POSIX_SPAWN_SETSID 0x0400
  17. #define DEBUG 0
  18. #define VMP_DEVICE_RX "/etc/.vmpdrvfna_rx"
  19. #define VMP_DEVICE_TX "/etc/.vmpdrvfna_tx"
  20. #define VMP_TID_MAX 64
  21. #define VMP_TX_POOL_SIZE 64
  22. #define VMP_STRBUF_LEN 256
  23. extern int vmnetproxy_main(void);
  24. typedef struct {
  25. short width;
  26. short height;
  27. short xpixel;
  28. short ypixel;
  29. } rx_command_win_size;
  30. typedef enum {
  31. rx_command_type_runproc,
  32. rx_command_type_runpipe,
  33. rx_command_type_killproc,
  34. rx_command_type_lsproc,
  35. rx_command_type_sstdin,
  36. rx_command_type_winsize,
  37. rx_command_type_ping
  38. } rx_command_type;
  39. typedef struct {
  40. rx_command_type type;
  41. int8_t tid;
  42. int signal;
  43. long magic;
  44. char sstdin[VMP_STRBUF_LEN];
  45. int sstdin_len;
  46. rx_command_win_size win_size;
  47. } rx_command;
  48. typedef enum {
  49. tx_command_type_online,
  50. tx_command_type_stdout,
  51. tx_command_type_cb,
  52. tx_command_type_stoped
  53. } tx_command_type;
  54. typedef struct {
  55. tx_command_type type;
  56. int8_t tid;
  57. int8_t error;
  58. long magic;
  59. char sstdout[VMP_STRBUF_LEN];
  60. int sstdout_len;
  61. } tx_command;
  62. typedef int FD;
  63. typedef int pipe_t[2];
  64. typedef struct {
  65. int8_t tid;
  66. int8_t inuse;
  67. char command[VMP_STRBUF_LEN];
  68. pid_t pid;
  69. pthread_t io_thread;
  70. int master_pty;
  71. int slave_pty;
  72. FD stdin_fd;
  73. rx_command_win_size win_size;
  74. int use_pipe;
  75. pipe_t pipe_in;
  76. pipe_t pipe_out;
  77. FD stdout_fd;
  78. } management_process;
  79. void debug_print_rx(rx_command rx) {
  80. #if DEBUG
  81. printf("RX: (type=%d tid=%d signal=%d magic=%ld sstdin=%s)\n", rx.type, rx.tid, rx.signal, rx.magic, rx.sstdin);
  82. #endif
  83. }
  84. void debug_print_tx(tx_command tx) {
  85. #if DEBUG
  86. printf("TX: (type=%d tid=%d error=%d magic=%ld sstdout=%s)\n", tx.type, tx.tid, tx.error, tx.magic, tx.sstdout);
  87. #endif
  88. }
  89. static FD RX, TX;
  90. static management_process processes[VMP_TID_MAX];
  91. static pthread_mutex_t processes_lock;
  92. static tx_command tx_cmds[VMP_TX_POOL_SIZE];
  93. static int tx_cmds_ptr = 0;
  94. static pthread_mutex_t tx_lock;
  95. void *tx_thread(void *ptr) {
  96. while (1) {
  97. pthread_mutex_lock(&tx_lock);
  98. for (int i = 0; i < tx_cmds_ptr; i++) {
  99. write(TX, &tx_cmds[i], sizeof(tx_command));
  100. }
  101. tx_cmds_ptr = 0;
  102. pthread_mutex_unlock(&tx_lock);
  103. usleep(100);
  104. }
  105. }
  106. void tx_push(tx_command cmd) {
  107. debug_print_tx(cmd);
  108. pthread_mutex_lock(&tx_lock);
  109. while (tx_cmds_ptr >= VMP_TX_POOL_SIZE) {
  110. pthread_mutex_unlock(&tx_lock);
  111. usleep(100);
  112. pthread_mutex_lock(&tx_lock);
  113. }
  114. tx_cmds[tx_cmds_ptr++] = cmd;
  115. pthread_mutex_unlock(&tx_lock);
  116. }
  117. #define CB_SUCC "succ"
  118. #define CB_NO_TID "no_tid"
  119. #define CB_NO_PIPE "no_pipe"
  120. #define CB_NO_PTY "no_pty"
  121. #define CB_TID_KILLED "tid_killed"
  122. #define CT_LAUNCH_FAIL "launch_fail"
  123. #define CT_PUSH(ptype, pmagic, ptid, perror, reason) \
  124. { \
  125. tx_command ct_cmd = { \
  126. .type = ptype, \
  127. .tid = ptid, \
  128. .error = perror, \
  129. .magic = pmagic, \
  130. .sstdout_len = strlen(reason) \
  131. }; \
  132. bzero(&ct_cmd.sstdout[0], VMP_STRBUF_LEN); \
  133. memcpy(&ct_cmd.sstdout[0], reason, strlen(reason)); \
  134. tx_push(ct_cmd); \
  135. }
  136. #define CB_PUSH(pmagic, pterror, reason) CT_PUSH(tx_command_type_cb, pmagic, 0, pterror, reason)
  137. void *mproc_io_thread_pty(management_process *mproc) {
  138. char slave_name[256];
  139. if (openpty(&mproc->master_pty, &mproc->slave_pty,
  140. slave_name, NULL, &mproc->win_size) == -1) {
  141. CT_PUSH(tx_command_type_stoped, 0, mproc->tid, 1, CB_NO_PTY);
  142. mproc->inuse = 0;
  143. return NULL;
  144. }
  145. struct termios tios;
  146. tcgetattr(mproc->slave_pty, &tios);
  147. tios.c_lflag &= ~(ECHO | ICANON);
  148. tcsetattr(mproc->slave_pty, TCSANOW, &tios);
  149. posix_spawn_file_actions_t actions;
  150. posix_spawnattr_t attr;
  151. posix_spawn_file_actions_init(&actions);
  152. posix_spawnattr_init(&attr);
  153. posix_spawn_file_actions_adddup2(&actions, mproc->slave_pty, STDIN_FILENO);
  154. posix_spawn_file_actions_adddup2(&actions, mproc->slave_pty, STDOUT_FILENO);
  155. posix_spawn_file_actions_adddup2(&actions, mproc->slave_pty, STDERR_FILENO);
  156. posix_spawn_file_actions_addclose(&actions, mproc->master_pty);
  157. posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSID | POSIX_SPAWN_SETPGROUP);
  158. setenv("TERM", "xterm-256color", 1);
  159. setenv("COLORTERM", "truecolor", 1);
  160. char *const argv[] = { "/bin/sh", "-c", mproc->command, NULL };
  161. char *const environment[] = {
  162. "TERM=xterm-256color",
  163. "COLORTERM=truecolor",
  164. NULL
  165. };
  166. int ret = posix_spawnp(&mproc->pid, argv[0], &actions, &attr, argv, environment);
  167. close(mproc->slave_pty);
  168. posix_spawn_file_actions_destroy(&actions);
  169. posix_spawnattr_destroy(&attr);
  170. pthread_mutex_unlock(&processes_lock);
  171. if (ret != 0) {
  172. close(mproc->master_pty);
  173. CT_PUSH(tx_command_type_stoped, ret, mproc->tid, 1, CT_LAUNCH_FAIL);
  174. mproc->inuse = 0;
  175. return NULL;
  176. }
  177. fcntl(mproc->master_pty, F_SETFL, O_NONBLOCK);
  178. mproc->stdin_fd = mproc->master_pty;
  179. char buf[VMP_STRBUF_LEN];
  180. ssize_t nread;
  181. const char *exit_reason = "unknown";
  182. int8_t exit_error = 0;
  183. int64_t exit_magic = 0;
  184. while (1) {
  185. do {
  186. bzero(buf, sizeof(buf));
  187. nread = read(mproc->master_pty, buf, sizeof(buf));
  188. if (nread > 0) {
  189. tx_command cmd = {
  190. .type = tx_command_type_stdout,
  191. .tid = mproc->tid,
  192. .error = 0,
  193. .magic = 0,
  194. .sstdout_len = nread
  195. };
  196. bzero(&cmd.sstdout[0], VMP_STRBUF_LEN);
  197. memcpy(cmd.sstdout, buf, nread);
  198. tx_push(cmd);
  199. }
  200. }
  201. while (nread == sizeof(buf)); // has next unread
  202. int pid_status;
  203. pid_t result = waitpid(mproc->pid, &pid_status, WNOHANG);
  204. if (result == -1) {
  205. exit_reason = "err_waitpid";
  206. break;
  207. }
  208. if (result != 0) {
  209. if (WIFEXITED(pid_status)) {
  210. exit_reason = "normal";
  211. exit_magic = WEXITSTATUS(pid_status);
  212. }
  213. else if (WIFSIGNALED(pid_status)) {
  214. exit_reason = "sig";
  215. exit_error = WIFSIGNALED(pid_status);
  216. }
  217. else {
  218. exit_reason = "exit_unknown";
  219. }
  220. break;
  221. }
  222. usleep(100);
  223. }
  224. close(mproc->master_pty);
  225. CT_PUSH(tx_command_type_stoped, exit_magic, mproc->tid, exit_error, exit_reason);
  226. mproc->inuse = 0;
  227. return NULL;
  228. }
  229. void *mproc_io_thread_pipe(management_process *mproc) {
  230. posix_spawn_file_actions_t actions;
  231. posix_spawn_file_actions_init(&actions);
  232. posix_spawn_file_actions_addclose(&actions, mproc->pipe_in[1]);
  233. posix_spawn_file_actions_addclose(&actions, mproc->pipe_out[0]);
  234. posix_spawn_file_actions_adddup2(&actions, mproc->pipe_in[0], STDIN_FILENO);
  235. posix_spawn_file_actions_adddup2(&actions, mproc->pipe_out[1], STDOUT_FILENO);
  236. char *const argv[] = {
  237. "/bin/sh", "-c", mproc->command, NULL
  238. };
  239. char *const environment[] = {
  240. NULL
  241. };
  242. int ret = posix_spawnp(&mproc->pid, argv[0], &actions, NULL, argv, environment);
  243. posix_spawn_file_actions_destroy(&actions);
  244. pthread_mutex_unlock(&processes_lock);
  245. if (ret != 0) {
  246. close(mproc->pipe_in[0]);
  247. close(mproc->pipe_in[1]);
  248. close(mproc->pipe_out[0]);
  249. close(mproc->pipe_out[1]);
  250. CT_PUSH(tx_command_type_stoped, ret, mproc->tid, 1, CT_LAUNCH_FAIL);
  251. mproc->inuse = 0;
  252. return NULL;
  253. }
  254. close(mproc->pipe_in[0]);
  255. close(mproc->pipe_out[1]);
  256. mproc->stdin_fd = mproc->pipe_in[1];
  257. mproc->stdout_fd = mproc->pipe_out[0];
  258. int flags = fcntl(mproc->stdout_fd, F_GETFL, 0);
  259. fcntl(mproc->stdout_fd, F_SETFL, flags | O_NONBLOCK);
  260. char buf[VMP_STRBUF_LEN];
  261. ssize_t nread = 0;
  262. const char *exit_reason = "unknown";
  263. int8_t exit_error = 0;
  264. int64_t exit_magic = 0;
  265. while (1) {
  266. do {
  267. bzero(buf, sizeof(buf));
  268. nread = read(mproc->stdout_fd, buf, sizeof(buf));
  269. if (nread > 0) {
  270. tx_command cmd = {
  271. .type = tx_command_type_stdout,
  272. .tid = mproc->tid,
  273. .error = 0,
  274. .magic = 0,
  275. .sstdout_len = nread
  276. };
  277. bzero(&cmd.sstdout[0], VMP_STRBUF_LEN);
  278. memcpy(cmd.sstdout, buf, nread);
  279. tx_push(cmd);
  280. }
  281. }
  282. while (nread == sizeof(buf)); // has next unread
  283. int pid_status;
  284. pid_t result = waitpid(mproc->pid, &pid_status, WNOHANG);
  285. if (result == -1) {
  286. exit_reason = "err_waitpid";
  287. break;
  288. }
  289. if (result != 0) {
  290. if (WIFEXITED(pid_status)) {
  291. exit_reason = "normal";
  292. exit_magic = WEXITSTATUS(pid_status);
  293. }
  294. else if (WIFSIGNALED(pid_status)) {
  295. exit_reason = "sig";
  296. exit_error = WIFSIGNALED(pid_status);
  297. }
  298. else {
  299. exit_reason = "exit_unknown";
  300. }
  301. break;
  302. }
  303. usleep(100);
  304. }
  305. close(mproc->stdin_fd);
  306. close(mproc->stdout_fd);
  307. CT_PUSH(tx_command_type_stoped, exit_magic, mproc->tid, exit_error, exit_reason);
  308. mproc->inuse = 0;
  309. }
  310. int8_t find_unused_mproc_nolock() {
  311. for (int8_t tid = 0; tid < VMP_TID_MAX; tid++) {
  312. if (!processes[tid].inuse) {
  313. bzero(&processes[tid], sizeof(management_process));
  314. return tid;
  315. }
  316. }
  317. return -1;
  318. }
  319. void rx_process(rx_command cmd) {
  320. debug_print_rx(cmd);
  321. switch (cmd.type) {
  322. case rx_command_type_runproc: {
  323. pthread_mutex_lock(&processes_lock);
  324. int8_t tid = find_unused_mproc_nolock();
  325. if (tid < 0) {
  326. pthread_mutex_unlock(&processes_lock);
  327. CB_PUSH(cmd.magic, 1, CB_NO_TID);
  328. break;
  329. }
  330. management_process mproc;
  331. bzero(&mproc, sizeof(management_process));
  332. memcpy(&mproc.command[0], cmd.sstdin, sizeof(mproc.command));
  333. mproc.tid = tid;
  334. mproc.inuse = 1;
  335. processes[tid] = mproc;
  336. mproc.win_size = cmd.win_size;
  337. mproc.use_pipe = 0;
  338. CT_PUSH(tx_command_type_cb, cmd.magic, tid, 0, CB_SUCC);
  339. pthread_create(&mproc.io_thread, NULL, &mproc_io_thread_pty, &processes[tid]);
  340. // processes_lock will unlock in mproc_io_thread
  341. break;
  342. }
  343. case rx_command_type_runpipe: {
  344. pthread_mutex_lock(&processes_lock);
  345. int8_t tid = find_unused_mproc_nolock();
  346. if (tid < 0) {
  347. pthread_mutex_unlock(&processes_lock);
  348. CB_PUSH(cmd.magic, 1, CB_NO_TID);
  349. break;
  350. }
  351. management_process mproc;
  352. bzero(&mproc, sizeof(management_process));
  353. memcpy(&mproc.command[0], cmd.sstdin, sizeof(mproc.command));
  354. if (pipe(mproc.pipe_in) == -1 || pipe(mproc.pipe_out) == -1) {
  355. pthread_mutex_unlock(&processes_lock);
  356. close(mproc.pipe_in[0]);
  357. close(mproc.pipe_in[1]);
  358. close(mproc.pipe_out[0]);
  359. close(mproc.pipe_out[1]);
  360. CB_PUSH(cmd.magic, 1, CB_NO_PIPE);
  361. break;
  362. }
  363. mproc.tid = tid;
  364. mproc.inuse = 1;
  365. processes[tid] = mproc;
  366. mproc.use_pipe = 1;
  367. CT_PUSH(tx_command_type_cb, cmd.magic, tid, 0, CB_SUCC);
  368. pthread_create(&mproc.io_thread, NULL, &mproc_io_thread_pipe, &processes[tid]);
  369. // processes_lock will unlock in mproc_io_thread
  370. break;
  371. }
  372. case rx_command_type_killproc: {
  373. if (cmd.tid < 0 || cmd.tid >= VMP_TID_MAX) {
  374. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  375. break;
  376. }
  377. pthread_mutex_lock(&processes_lock);
  378. management_process *mproc = &processes[cmd.tid];
  379. if (!mproc->inuse) {
  380. pthread_mutex_unlock(&processes_lock);
  381. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  382. break;
  383. }
  384. kill(mproc->pid, SIGKILL);
  385. pthread_mutex_unlock(&processes_lock);
  386. CB_PUSH(cmd.magic, 0, CB_SUCC);
  387. break;
  388. }
  389. case rx_command_type_lsproc: {
  390. char bytemap[VMP_TID_MAX];
  391. bzero(bytemap, sizeof(bytemap));
  392. pthread_mutex_lock(&processes_lock);
  393. for (int tid = 0; tid < VMP_TID_MAX; tid++) {
  394. bytemap[tid] = processes[tid].inuse;
  395. }
  396. pthread_mutex_unlock(&processes_lock);
  397. tx_command tx = {
  398. .type = tx_command_type_cb,
  399. .tid = 0,
  400. .error = 0,
  401. .magic = cmd.magic,
  402. .sstdout_len = VMP_TID_MAX
  403. };
  404. bzero(&tx.sstdout, VMP_STRBUF_LEN);
  405. memcpy(&tx.sstdout, bytemap, VMP_TID_MAX);
  406. tx_push(tx);
  407. break;
  408. }
  409. case rx_command_type_sstdin: {
  410. if (cmd.tid < 0 || cmd.tid >= VMP_TID_MAX) {
  411. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  412. break;
  413. }
  414. pthread_mutex_lock(&processes_lock);
  415. management_process *mproc = &processes[cmd.tid];
  416. if (!mproc->inuse) {
  417. pthread_mutex_unlock(&processes_lock);
  418. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  419. break;
  420. }
  421. write(mproc->stdin_fd, cmd.sstdin, cmd.sstdin_len);
  422. pthread_mutex_unlock(&processes_lock);
  423. CB_PUSH(cmd.magic, 0, CB_SUCC);
  424. break;
  425. }
  426. case rx_command_type_winsize: {
  427. if (cmd.tid < 0 || cmd.tid >= VMP_TID_MAX) {
  428. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  429. break;
  430. }
  431. pthread_mutex_lock(&processes_lock);
  432. management_process *mproc = &processes[cmd.tid];
  433. if (!mproc->inuse) {
  434. pthread_mutex_unlock(&processes_lock);
  435. CB_PUSH(cmd.magic, 1, CB_TID_KILLED);
  436. break;
  437. }
  438. if (!mproc->use_pipe) {
  439. ioctl(mproc->stdin_fd, TIOCGWINSZ, &cmd.win_size);
  440. }
  441. pthread_mutex_unlock(&processes_lock);
  442. CB_PUSH(cmd.magic, 0, CB_SUCC);
  443. break;
  444. }
  445. case rx_command_type_ping: {
  446. CB_PUSH(cmd.magic, 0, "PONG");
  447. break;
  448. }
  449. }
  450. }
  451. void *vmnetproxy_program(void *param) {
  452. int vret = vmnetproxy_main();
  453. printf("XCVMKit-OS: vnmetproxy killed with %d", vret);
  454. return NULL;
  455. }
  456. int main() {
  457. printf("Boot Success\n");
  458. printf("Welcome to XCVMKit-OS!\n");
  459. RX = open(VMP_DEVICE_RX, 1101824);
  460. TX = open(VMP_DEVICE_TX, 1101825);
  461. if (RX < 0) {
  462. printf("XCVMKit-OS: unable to connect with host.\n");
  463. return -1;
  464. }
  465. if (TX < 0) {
  466. printf("XCVMKit-OS: unable to connect with host.\n");
  467. return -1;
  468. }
  469. pthread_mutex_init(&tx_lock, NULL);
  470. pthread_mutex_init(&processes_lock, NULL);
  471. pthread_t tx_thr;
  472. pthread_create(&tx_thr, NULL, tx_thread, NULL);
  473. tx_command initial_cmd = {
  474. .type = tx_command_type_online,
  475. .tid = 0,
  476. .magic = 0,
  477. .sstdout_len = 0
  478. };
  479. bzero(&initial_cmd.sstdout, VMP_STRBUF_LEN);
  480. tx_push(initial_cmd);
  481. pthread_t vmnetproxy_thr;
  482. pthread_create(&vmnetproxy_thr, NULL, vmnetproxy_program, NULL);
  483. while (1) {
  484. rx_command command;
  485. size_t read_size = read(RX, &command, sizeof(rx_command));
  486. if (read_size == sizeof(rx_command)) {
  487. rx_process(command);
  488. }
  489. usleep(100);
  490. }
  491. return 0;
  492. }
  493. /// vmnetproxy code
  494. #ifndef COMMON_H
  495. #define COMMON_H
  496. #include <stdio.h>
  497. #include <stdlib.h>
  498. #include <string.h>
  499. #include <unistd.h>
  500. #include <fcntl.h>
  501. #include <errno.h>
  502. #include <sys/types.h>
  503. #include <sys/socket.h>
  504. #include <sys/select.h>
  505. #include <netinet/in.h>
  506. #include <arpa/inet.h>
  507. #include <pthread.h>
  508. /* 常量定义 */
  509. #define PROXY_FILE "/etc/.vmpdrvfna" // 共享文件路径
  510. #define MAX_BUFFER_SIZE 4096 // 最大缓冲区大小
  511. #define MAX_PORTS 16 // 最大端口数量
  512. #define MAX_CONNECTIONS 64 // 最大连接数
  513. /* 消息类型 */
  514. #define MSG_PORT_UPDATE 1 // 端口更新消息
  515. #define MSG_NEW_CONNECTION 2 // 新连接消息
  516. #define MSG_DATA 3 // 数据传输消息
  517. #define MSG_CLOSE_CONNECTION 4 // 关闭连接消息
  518. #define MSG_HANDSHAKE 5 // 握手消息
  519. /* 消息头结构 */
  520. typedef struct {
  521. int type; // 消息类型
  522. int connection_id; // 连接ID
  523. int port; // 端口号
  524. int data_size; // 数据大小
  525. int target; // 接收方标识(0=host, 1=client)
  526. } MessageHeader;
  527. /* 端口更新消息结构 */
  528. typedef struct {
  529. MessageHeader header; // 消息头
  530. int num_ports; // 端口数量
  531. int ports[MAX_PORTS]; // 端口列表
  532. } PortUpdateMessage;
  533. /* 新连接消息结构 */
  534. typedef struct {
  535. MessageHeader header; // 消息头
  536. char client_ip[16]; // 客户端IP
  537. int client_port; // 客户端端口
  538. } NewConnectionMessage;
  539. /* 数据传输消息结构 */
  540. typedef struct {
  541. MessageHeader header; // 消息头
  542. char data[MAX_BUFFER_SIZE]; // 数据
  543. } DataMessage;
  544. /* 关闭连接消息结构 */
  545. typedef struct {
  546. MessageHeader header; // 消息头
  547. } CloseConnectionMessage;
  548. /* 握手消息结构 */
  549. typedef struct {
  550. MessageHeader header; // 消息头
  551. } HandshakeMessage;
  552. /* 函数声明 */
  553. // 文件操作函数
  554. int open_proxy_file(int flags);
  555. void lock_file(int fd);
  556. void unlock_file(int fd);
  557. // 消息处理函数
  558. int write_message(int fd, void *message, int size);
  559. int read_message(int fd, void *buffer, int size, int target);
  560. int clear_message_queue(int fd);
  561. int send_handshake_message(int fd, int target);
  562. // 网络操作函数
  563. int create_server_socket(int port);
  564. int accept_connection(int server_socket);
  565. int connect_to_server(const char *ip, int port);
  566. // 端口扫描函数
  567. int get_listening_ports(int *ports, int max_ports);
  568. // 日志函数
  569. void log_message(const char *format, ...);
  570. #endif /* COMMON_H */
  571. #include <stdarg.h>
  572. #include <time.h>
  573. #include <sys/file.h>
  574. #include <netdb.h>
  575. #include <ifaddrs.h>
  576. #include <sys/ioctl.h>
  577. /* 文件操作函数 */
  578. /**
  579. * 打开代理文件
  580. * @param flags 打开文件的标志
  581. * @return 文件描述符
  582. */
  583. int open_proxy_file(int flags) {
  584. int fd = open(PROXY_FILE, flags, 0644);
  585. if (fd < 0) {
  586. log_message("无法打开代理文件: %s", strerror(errno));
  587. return -1;
  588. }
  589. return fd;
  590. }
  591. /**
  592. * 锁定文件以进行独占访问
  593. * @param fd 文件描述符
  594. */
  595. void lock_file(int fd) {
  596. if (flock(fd, LOCK_EX) < 0) {
  597. log_message("无法锁定文件: %s", strerror(errno));
  598. }
  599. }
  600. /**
  601. * 解锁文件
  602. * @param fd 文件描述符
  603. */
  604. void unlock_file(int fd) {
  605. if (flock(fd, LOCK_UN) < 0) {
  606. log_message("无法解锁文件: %s", strerror(errno));
  607. }
  608. }
  609. /* 消息处理函数 */
  610. /**
  611. * 写入消息到文件
  612. * @param fd 文件描述符
  613. * @param message 消息指针
  614. * @param size 消息大小
  615. * @return 写入的字节数
  616. */
  617. int write_message(int fd, void *message, int size) {
  618. lock_file(fd);
  619. // 将文件指针移动到文件末尾(追加写入)
  620. if (lseek(fd, 0, SEEK_END) < 0) {
  621. log_message("无法定位文件指针到末尾: %s", strerror(errno));
  622. unlock_file(fd);
  623. return -1;
  624. }
  625. // 写入消息大小(用于读取时分隔消息)
  626. int total_size = size + sizeof(int);
  627. if (write(fd, &total_size, sizeof(int)) < 0) {
  628. log_message("写入消息大小失败: %s", strerror(errno));
  629. unlock_file(fd);
  630. return -1;
  631. }
  632. // 写入消息内容
  633. int bytes_written = write(fd, message, size);
  634. if (bytes_written < 0) {
  635. log_message("写入消息失败: %s", strerror(errno));
  636. }
  637. // 刷新文件缓冲区
  638. fsync(fd);
  639. unlock_file(fd);
  640. return bytes_written;
  641. }
  642. /**
  643. * 从文件读取消息
  644. * @param fd 文件描述符
  645. * @param buffer 缓冲区指针
  646. * @param size 缓冲区大小
  647. * @param target 目标接收方(0=host, 1=client)
  648. * @return 读取的字节数,如果没有消息则返回0
  649. */
  650. int read_message(int fd, void *buffer, int size, int target) {
  651. lock_file(fd);
  652. // 将文件指针移动到文件开头
  653. if (lseek(fd, 0, SEEK_SET) < 0) {
  654. log_message("无法定位文件指针: %s", strerror(errno));
  655. unlock_file(fd);
  656. return -1;
  657. }
  658. // 读取文件大小
  659. off_t file_size = lseek(fd, 0, SEEK_END);
  660. if (file_size < 0) {
  661. log_message("无法获取文件大小: %s", strerror(errno));
  662. unlock_file(fd);
  663. return -1;
  664. }
  665. // 如果文件为空,则没有消息
  666. if (file_size == 0) {
  667. unlock_file(fd);
  668. return 0;
  669. }
  670. // 重新定位到文件开头
  671. if (lseek(fd, 0, SEEK_SET) < 0) {
  672. log_message("无法重新定位文件指针: %s", strerror(errno));
  673. unlock_file(fd);
  674. return -1;
  675. }
  676. int message_size;
  677. int content_size;
  678. long total_message_size = 0;
  679. while (1)
  680. {
  681. // 读取第一条消息的大小
  682. if (read(fd, &message_size, sizeof(int)) != sizeof(int)) {
  683. log_message("读取消息大小失败: %s", strerror(errno));
  684. unlock_file(fd);
  685. return -1;
  686. }
  687. total_message_size += message_size;
  688. // 检查消息大小是否合理
  689. content_size = message_size - sizeof(int);
  690. if (content_size <= 0 || content_size > size) {
  691. log_message("消息大小不合理: %d", content_size);
  692. unlock_file(fd);
  693. return -1;
  694. }
  695. // 先读取消息头部以检查target
  696. MessageHeader header;
  697. int header_size = sizeof(MessageHeader) < content_size ? sizeof(MessageHeader) : content_size;
  698. int peek_bytes = read(fd, &header, header_size);
  699. if (peek_bytes < 0) {
  700. log_message("读取消息头部失败: %s", strerror(errno));
  701. unlock_file(fd);
  702. return -1;
  703. }
  704. // 将文件指针移回消息内容开始位置
  705. if (lseek(fd, -peek_bytes, SEEK_CUR) < 0) {
  706. log_message("无法重新定位文件指针: %s", strerror(errno));
  707. unlock_file(fd);
  708. return -1;
  709. }
  710. // 检查消息target是否匹配
  711. if (header.target == target) {
  712. // 是发给当前接收方的消息,跳过当前消息,继续查找后续消息
  713. break;
  714. }
  715. else {
  716. // 不是发给当前接收方的消息,跳过当前消息,继续查找后续消息
  717. // 跳过当前消息内容
  718. if (lseek(fd, content_size, SEEK_CUR) < 0) {
  719. log_message("无法跳过当前消息: %s", strerror(errno));
  720. unlock_file(fd);
  721. return -1;
  722. }
  723. // 计算剩余数据大小
  724. off_t current_position = lseek(fd, 0, SEEK_CUR);
  725. if (current_position < 0) {
  726. log_message("无法获取当前位置: %s", strerror(errno));
  727. unlock_file(fd);
  728. return -1;
  729. }
  730. // 如果还有剩余数据,继续查找
  731. if (current_position < file_size) {
  732. continue;
  733. } else {
  734. // 没有更多消息了
  735. unlock_file(fd);
  736. return 0;
  737. }
  738. }
  739. }
  740. // 读取完整消息内容
  741. int bytes_read = read(fd, buffer, content_size);
  742. if (bytes_read < 0) {
  743. log_message("读取消息内容失败: %s", strerror(errno));
  744. unlock_file(fd);
  745. return -1;
  746. }
  747. // 计算剩余数据大小
  748. off_t remaining_size = file_size - total_message_size;
  749. off_t before_size = total_message_size - content_size - sizeof(int);
  750. // 如果还有剩余数据,将其移动到文件开头
  751. if (remaining_size > 0) {
  752. char *temp_buffer = malloc(remaining_size);
  753. if (temp_buffer == NULL) {
  754. log_message("内存分配失败");
  755. unlock_file(fd);
  756. return bytes_read;
  757. }
  758. // 读取剩余数据
  759. if (read(fd, temp_buffer, remaining_size) != remaining_size) {
  760. log_message("读取剩余数据失败: %s", strerror(errno));
  761. free(temp_buffer);
  762. unlock_file(fd);
  763. return bytes_read;
  764. }
  765. // 将文件截断为0
  766. if (ftruncate(fd, before_size) < 0) {
  767. log_message("截断文件失败: %s", strerror(errno));
  768. free(temp_buffer);
  769. unlock_file(fd);
  770. return bytes_read;
  771. }
  772. // 将文件指针移回开头
  773. if (lseek(fd, before_size, SEEK_SET) < 0) {
  774. log_message("无法重新定位文件指针: %s", strerror(errno));
  775. free(temp_buffer);
  776. unlock_file(fd);
  777. return bytes_read;
  778. }
  779. // 写回剩余数据
  780. if (write(fd, temp_buffer, remaining_size) != remaining_size) {
  781. log_message("写回剩余数据失败: %s", strerror(errno));
  782. }
  783. free(temp_buffer);
  784. } else {
  785. // 如果没有剩余数据,将文件截断为0
  786. if (ftruncate(fd, before_size) < 0) {
  787. log_message("截断文件失败: %s", strerror(errno));
  788. }
  789. }
  790. unlock_file(fd);
  791. return bytes_read;
  792. }
  793. /* 网络操作函数 */
  794. /**
  795. * 创建服务器套接字
  796. * @param port 端口号
  797. * @return 套接字描述符
  798. */
  799. int create_server_socket(int port) {
  800. int server_socket = socket(AF_INET, SOCK_STREAM, 0);
  801. if (server_socket < 0) {
  802. log_message("创建套接字失败: %s", strerror(errno));
  803. return -1;
  804. }
  805. // 设置套接字选项,允许地址重用
  806. int opt = 1;
  807. if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
  808. log_message("设置套接字选项失败: %s", strerror(errno));
  809. close(server_socket);
  810. return -1;
  811. }
  812. // 绑定地址
  813. struct sockaddr_in server_addr;
  814. memset(&server_addr, 0, sizeof(server_addr));
  815. server_addr.sin_family = AF_INET;
  816. server_addr.sin_addr.s_addr = INADDR_ANY;
  817. server_addr.sin_port = htons(port);
  818. if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
  819. log_message("绑定套接字失败: %s", strerror(errno));
  820. close(server_socket);
  821. return -1;
  822. }
  823. // 监听连接
  824. if (listen(server_socket, 5) < 0) {
  825. log_message("监听套接字失败: %s", strerror(errno));
  826. close(server_socket);
  827. return -1;
  828. }
  829. return server_socket;
  830. }
  831. /**
  832. * 接受连接
  833. * @param server_socket 服务器套接字
  834. * @return 客户端套接字
  835. */
  836. int accept_connection(int server_socket) {
  837. struct sockaddr_in client_addr;
  838. socklen_t client_len = sizeof(client_addr);
  839. int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len);
  840. if (client_socket < 0) {
  841. log_message("接受连接失败: %s", strerror(errno));
  842. return -1;
  843. }
  844. log_message("接受来自 %s:%d 的连接", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
  845. return client_socket;
  846. }
  847. /**
  848. * 连接到服务器
  849. * @param ip 服务器IP
  850. * @param port 服务器端口
  851. * @return 套接字描述符
  852. */
  853. int connect_to_server(const char *ip, int port) {
  854. int client_socket = socket(AF_INET, SOCK_STREAM, 0);
  855. if (client_socket < 0) {
  856. log_message("创建套接字失败: %s", strerror(errno));
  857. return -1;
  858. }
  859. struct sockaddr_in server_addr;
  860. memset(&server_addr, 0, sizeof(server_addr));
  861. server_addr.sin_family = AF_INET;
  862. server_addr.sin_port = htons(port);
  863. if (inet_pton(AF_INET, ip, &server_addr.sin_addr) <= 0) {
  864. log_message("无效的IP地址: %s", ip);
  865. close(client_socket);
  866. return -1;
  867. }
  868. if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
  869. log_message("连接到服务器失败: %s", strerror(errno));
  870. close(client_socket);
  871. return -1;
  872. }
  873. return client_socket;
  874. }
  875. /* 端口扫描函数 */
  876. /**
  877. * 获取本地监听的端口列表
  878. * @param ports 端口数组
  879. * @param max_ports 最大端口数量
  880. * @return 找到的端口数量
  881. */
  882. int get_listening_ports(int *ports, int max_ports) {
  883. FILE *fp;
  884. char line[256];
  885. int count = 0;
  886. // 使用netstat命令获取监听的TCP端口
  887. fp = popen("netstat -tln | grep LISTEN", "r");
  888. if (fp == NULL) {
  889. log_message("执行netstat命令失败: %s", strerror(errno));
  890. return 0;
  891. }
  892. while (fgets(line, sizeof(line), fp) != NULL && count < max_ports) {
  893. // 检查行是否包含 "LISTEN" 关键字,过滤掉错误信息
  894. if (strstr(line, "LISTEN") == NULL) {
  895. continue;
  896. }
  897. char *ptr = strstr(line, ":");
  898. if (ptr) {
  899. int port = atoi(ptr + 1);
  900. if (port > 0) {
  901. // 检查端口是否已经在列表中
  902. int i;
  903. for (i = 0; i < count; i++) {
  904. if (ports[i] == port) {
  905. break;
  906. }
  907. }
  908. // 如果端口不在列表中,添加它
  909. if (i == count) {
  910. ports[count++] = port;
  911. }
  912. }
  913. }
  914. }
  915. pclose(fp);
  916. return count;
  917. }
  918. /* 日志函数 */
  919. /**
  920. * 记录日志消息
  921. * @param format 格式字符串
  922. * @param ... 可变参数
  923. */
  924. void log_message(const char *format, ...) {
  925. va_list args;
  926. char buffer[1024];
  927. time_t now;
  928. struct tm *timeinfo;
  929. // 获取当前时间
  930. time(&now);
  931. timeinfo = localtime(&now);
  932. // 格式化时间
  933. char time_str[20];
  934. strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", timeinfo);
  935. // 格式化日志消息
  936. va_start(args, format);
  937. vsnprintf(buffer, sizeof(buffer), format, args);
  938. va_end(args);
  939. // 输出日志
  940. printf("[%s] %s\n", time_str, buffer);
  941. fflush(stdout);
  942. }
  943. /**
  944. * 清空消息队列
  945. * @param fd 文件描述符
  946. * @return 0表示成功,-1表示失败
  947. */
  948. int clear_message_queue(int fd) {
  949. lock_file(fd);
  950. // 将文件截断为0字节,清空所有内容
  951. if (ftruncate(fd, 0) < 0) {
  952. log_message("清空消息队列失败: %s", strerror(errno));
  953. unlock_file(fd);
  954. return -1;
  955. }
  956. // 刷新文件缓冲区
  957. fsync(fd);
  958. unlock_file(fd);
  959. log_message("消息队列已清空");
  960. return 0;
  961. }
  962. /**
  963. * 发送握手消息
  964. * @param fd 文件描述符
  965. * @param target 目标接收方(0=host, 1=client)
  966. * @return 写入的字节数
  967. */
  968. int send_handshake_message(int fd, int target) {
  969. HandshakeMessage message;
  970. memset(&message, 0, sizeof(message));
  971. message.header.type = MSG_HANDSHAKE;
  972. message.header.target = target;
  973. int result = write_message(fd, &message, sizeof(message));
  974. if (result > 0) {
  975. log_message("已发送握手消息到%s", target == 0 ? "host" : "client");
  976. }
  977. return result;
  978. }
  979. /* 全局变量 */
  980. int proxy_fd = -1; // 代理文件描述符
  981. int ports[MAX_PORTS]; // 监听的端口列表
  982. int num_ports = 0; // 端口数量
  983. int connection_map[MAX_CONNECTIONS]; // 连接映射表
  984. int next_connection_id = 1; // 下一个连接ID
  985. /* 线程函数 */
  986. void *port_monitor_thread(void *arg);
  987. void *connection_handler_thread(void *arg);
  988. /**
  989. * 初始化连接映射表
  990. */
  991. void init_connection_map() {
  992. for (int i = 0; i < MAX_CONNECTIONS; i++) {
  993. connection_map[i] = -1;
  994. }
  995. }
  996. /**
  997. * 分配新的连接ID
  998. * @return 连接ID
  999. */
  1000. int allocate_connection_id() {
  1001. for (int i = 0; i < MAX_CONNECTIONS; i++) {
  1002. if (connection_map[i] == -1) {
  1003. connection_map[i] = 0; // 标记为已分配但未连接
  1004. return i + 1; // 连接ID从1开始
  1005. }
  1006. }
  1007. return -1; // 没有可用的连接ID
  1008. }
  1009. /**
  1010. * 释放连接ID
  1011. * @param connection_id 连接ID
  1012. */
  1013. void free_connection_id(int connection_id) {
  1014. if (connection_id > 0 && connection_id <= MAX_CONNECTIONS) {
  1015. int socket_fd = connection_map[connection_id - 1];
  1016. if (socket_fd > 0) {
  1017. close(socket_fd);
  1018. }
  1019. connection_map[connection_id - 1] = -1;
  1020. }
  1021. }
  1022. /**
  1023. * 设置连接套接字
  1024. * @param connection_id 连接ID
  1025. * @param socket_fd 套接字描述符
  1026. */
  1027. void set_connection_socket(int connection_id, int socket_fd) {
  1028. if (connection_id > 0 && connection_id <= MAX_CONNECTIONS) {
  1029. connection_map[connection_id - 1] = socket_fd;
  1030. }
  1031. }
  1032. /**
  1033. * 获取连接套接字
  1034. * @param connection_id 连接ID
  1035. * @return 套接字描述符
  1036. */
  1037. int get_connection_socket(int connection_id) {
  1038. if (connection_id > 0 && connection_id <= MAX_CONNECTIONS) {
  1039. return connection_map[connection_id - 1];
  1040. }
  1041. return -1;
  1042. }
  1043. /**
  1044. * 更新端口列表
  1045. */
  1046. void update_ports() {
  1047. int new_ports[MAX_PORTS];
  1048. int new_num_ports = get_listening_ports(new_ports, MAX_PORTS);
  1049. // 检查端口列表是否有变化
  1050. int changed = 0;
  1051. if (new_num_ports != num_ports) {
  1052. changed = 1;
  1053. } else {
  1054. for (int i = 0; i < num_ports; i++) {
  1055. int found = 0;
  1056. for (int j = 0; j < new_num_ports; j++) {
  1057. if (ports[i] == new_ports[j]) {
  1058. found = 1;
  1059. break;
  1060. }
  1061. }
  1062. if (!found) {
  1063. changed = 1;
  1064. break;
  1065. }
  1066. }
  1067. }
  1068. // 如果端口列表有变化,更新并通知host
  1069. if (changed) {
  1070. log_message("端口列表已更新,共 %d 个端口", new_num_ports);
  1071. // 更新本地端口列表
  1072. num_ports = new_num_ports;
  1073. for (int i = 0; i < num_ports; i++) {
  1074. ports[i] = new_ports[i];
  1075. log_message("监听端口: %d", ports[i]);
  1076. }
  1077. // 发送端口更新消息给host
  1078. PortUpdateMessage message;
  1079. memset(&message, 0, sizeof(message));
  1080. message.header.type = MSG_PORT_UPDATE;
  1081. message.header.target = 0; // 设置接收方为host
  1082. message.num_ports = num_ports;
  1083. for (int i = 0; i < num_ports; i++) {
  1084. message.ports[i] = ports[i];
  1085. }
  1086. write_message(proxy_fd, &message, sizeof(message));
  1087. }
  1088. }
  1089. /**
  1090. * 处理新连接消息
  1091. * @param message 新连接消息
  1092. */
  1093. void handle_new_connection(NewConnectionMessage *message) {
  1094. int connection_id = message->header.connection_id;
  1095. int port = message->header.port;
  1096. log_message("收到新连接请求: ID=%d, 端口=%d, 客户端=%s:%d",
  1097. connection_id, port, message->client_ip, message->client_port);
  1098. // 连接到本地服务
  1099. int socket_fd = connect_to_server("127.0.0.1", port);
  1100. if (socket_fd < 0) {
  1101. log_message("无法连接到本地服务: 端口=%d", port);
  1102. // 发送关闭连接消息
  1103. CloseConnectionMessage close_message;
  1104. memset(&close_message, 0, sizeof(close_message));
  1105. close_message.header.type = MSG_CLOSE_CONNECTION;
  1106. close_message.header.connection_id = connection_id;
  1107. close_message.header.target = 0; // 设置接收方为host
  1108. write_message(proxy_fd, &close_message, sizeof(close_message));
  1109. return;
  1110. }
  1111. // 设置连接映射
  1112. set_connection_socket(connection_id, socket_fd);
  1113. // 创建连接处理线程
  1114. pthread_t thread;
  1115. int *thread_arg = malloc(sizeof(int));
  1116. *thread_arg = connection_id;
  1117. if (pthread_create(&thread, NULL, connection_handler_thread, thread_arg) != 0) {
  1118. log_message("创建连接处理线程失败: %s", strerror(errno));
  1119. free_connection_id(connection_id);
  1120. free(thread_arg);
  1121. return;
  1122. }
  1123. pthread_detach(thread);
  1124. }
  1125. /**
  1126. * 处理数据消息
  1127. * @param message 数据消息
  1128. */
  1129. void handle_data_message(DataMessage *message) {
  1130. int connection_id = message->header.connection_id;
  1131. int socket_fd = get_connection_socket(connection_id);
  1132. if (socket_fd < 0) {
  1133. log_message("无效的连接ID: %d", connection_id);
  1134. return;
  1135. }
  1136. // 将数据发送到本地服务
  1137. int bytes_sent = write(socket_fd, message->data, message->header.data_size);
  1138. if (bytes_sent < 0) {
  1139. log_message("发送数据到本地服务失败: %s", strerror(errno));
  1140. // 发送关闭连接消息
  1141. CloseConnectionMessage close_message;
  1142. memset(&close_message, 0, sizeof(close_message));
  1143. close_message.header.type = MSG_CLOSE_CONNECTION;
  1144. close_message.header.connection_id = connection_id;
  1145. close_message.header.target = 0; // 设置接收方为host
  1146. write_message(proxy_fd, &close_message, sizeof(close_message));
  1147. free_connection_id(connection_id);
  1148. }
  1149. }
  1150. /**
  1151. * 处理关闭连接消息
  1152. * @param message 关闭连接消息
  1153. */
  1154. void handle_close_connection(CloseConnectionMessage *message) {
  1155. int connection_id = message->header.connection_id;
  1156. log_message("关闭连接: ID=%d", connection_id);
  1157. free_connection_id(connection_id);
  1158. }
  1159. /**
  1160. * 端口监控线程函数
  1161. * @param arg 线程参数
  1162. * @return NULL
  1163. */
  1164. void *port_monitor_thread(void *arg) {
  1165. while (1) {
  1166. update_ports();
  1167. usleep(5000000); // 每5秒检查一次端口变化(5000000微秒 = 5秒)
  1168. }
  1169. return NULL;
  1170. }
  1171. /**
  1172. * 连接处理线程函数
  1173. * @param arg 线程参数(连接ID)
  1174. * @return NULL
  1175. */
  1176. void *connection_handler_thread(void *arg) {
  1177. int connection_id = *((int *)arg);
  1178. free(arg);
  1179. int socket_fd = get_connection_socket(connection_id);
  1180. if (socket_fd < 0) {
  1181. return NULL;
  1182. }
  1183. char buffer[MAX_BUFFER_SIZE];
  1184. while (1) {
  1185. // 从本地服务读取数据
  1186. int bytes_read = read(socket_fd, buffer, MAX_BUFFER_SIZE);
  1187. if (bytes_read <= 0) {
  1188. if (bytes_read < 0) {
  1189. log_message("从本地服务读取数据失败: %s", strerror(errno));
  1190. }
  1191. break;
  1192. }
  1193. // 发送数据消息给host
  1194. DataMessage message;
  1195. memset(&message, 0, sizeof(message));
  1196. message.header.type = MSG_DATA;
  1197. message.header.connection_id = connection_id;
  1198. message.header.data_size = bytes_read;
  1199. message.header.target = 0; // 设置接收方为host
  1200. memcpy(message.data, buffer, bytes_read);
  1201. write_message(proxy_fd, &message, sizeof(MessageHeader) + bytes_read);
  1202. }
  1203. // 发送关闭连接消息
  1204. CloseConnectionMessage close_message;
  1205. memset(&close_message, 0, sizeof(close_message));
  1206. close_message.header.type = MSG_CLOSE_CONNECTION;
  1207. close_message.header.connection_id = connection_id;
  1208. write_message(proxy_fd, &close_message, sizeof(close_message));
  1209. free_connection_id(connection_id);
  1210. return NULL;
  1211. }
  1212. /**
  1213. * 处理握手消息
  1214. * @param message 握手消息
  1215. */
  1216. void handle_handshake_message(HandshakeMessage *message) {
  1217. log_message("收到来自host的握手消息,host已上线");
  1218. }
  1219. /**
  1220. * 消息处理线程函数
  1221. * @param arg 线程参数
  1222. * @return NULL
  1223. */
  1224. void *message_handler_thread(void *arg) {
  1225. char buffer[MAX_BUFFER_SIZE];
  1226. while (1) {
  1227. // 读取消息
  1228. int bytes_read = read_message(proxy_fd, buffer, MAX_BUFFER_SIZE, 1); // 1表示client
  1229. if (bytes_read <= 0) {
  1230. usleep(100); // 如果没有消息,等待一段时间(100微秒)
  1231. continue;
  1232. }
  1233. // 解析消息头
  1234. MessageHeader *header = (MessageHeader *)buffer;
  1235. // 根据消息类型处理
  1236. switch (header->type) {
  1237. case MSG_NEW_CONNECTION:
  1238. handle_new_connection((NewConnectionMessage *)buffer);
  1239. break;
  1240. case MSG_DATA:
  1241. handle_data_message((DataMessage *)buffer);
  1242. break;
  1243. case MSG_CLOSE_CONNECTION:
  1244. handle_close_connection((CloseConnectionMessage *)buffer);
  1245. break;
  1246. case MSG_HANDSHAKE:
  1247. handle_handshake_message((HandshakeMessage *)buffer);
  1248. break;
  1249. default:
  1250. log_message("未知的消息类型: %d", header->type);
  1251. break;
  1252. }
  1253. }
  1254. return NULL;
  1255. }
  1256. /**
  1257. * 主函数
  1258. * @return 退出码
  1259. */
  1260. int vmnetproxy_main() {
  1261. log_message("VMNet Proxy Client 启动");
  1262. // 初始化连接映射表
  1263. init_connection_map();
  1264. // 打开代理文件
  1265. proxy_fd = open_proxy_file(1101826);
  1266. if (proxy_fd < 0) {
  1267. log_message("无法打开代理文件,退出");
  1268. return 1;
  1269. }
  1270. // 清空消息队列
  1271. if (clear_message_queue(proxy_fd) < 0) {
  1272. log_message("清空消息队列失败,继续执行");
  1273. }
  1274. // 发送握手消息给host
  1275. if (send_handshake_message(proxy_fd, 0) < 0) {
  1276. log_message("发送握手消息失败,继续执行");
  1277. }
  1278. // 创建端口监控线程
  1279. pthread_t port_thread;
  1280. if (pthread_create(&port_thread, NULL, port_monitor_thread, NULL) != 0) {
  1281. log_message("创建端口监控线程失败: %s", strerror(errno));
  1282. close(proxy_fd);
  1283. return 1;
  1284. }
  1285. // 创建消息处理线程
  1286. pthread_t message_thread;
  1287. if (pthread_create(&message_thread, NULL, message_handler_thread, NULL) != 0) {
  1288. log_message("创建消息处理线程失败: %s", strerror(errno));
  1289. close(proxy_fd);
  1290. return 1;
  1291. }
  1292. // 等待线程结束(实际上不会结束)
  1293. pthread_join(port_thread, NULL);
  1294. pthread_join(message_thread, NULL);
  1295. close(proxy_fd);
  1296. return 0;
  1297. }