socket.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. // original : core.c 2003/02/26 18:03:12 Rev 1.7
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <errno.h>
  6. #ifdef _WIN32
  7. #define WIN32_LEAN_AND_MEAN
  8. #include <windows.h>
  9. #include <winsock2.h>
  10. #include <io.h>
  11. typedef int socklen_t;
  12. #else
  13. #include <sys/socket.h>
  14. #include <netinet/in.h>
  15. #include <netinet/tcp.h>
  16. #include <net/if.h>
  17. #include <sys/time.h>
  18. #include <unistd.h>
  19. #include <sys/ioctl.h>
  20. #ifndef SIOCGIFCONF
  21. #include <sys/sockio.h> // SIOCGIFCONF on Solaris, maybe others? [Shinomori]
  22. #endif
  23. #endif
  24. #include <fcntl.h>
  25. #include <string.h>
  26. #include "mmo.h" // [Valaris] thanks to fov
  27. #include "socket.h"
  28. #include "utils.h"
  29. #ifdef MEMWATCH
  30. #include "memwatch.h"
  31. #endif
  32. fd_set readfds;
  33. int fd_max;
  34. time_t tick_;
  35. time_t stall_time_ = 60;
  36. int rfifo_size = 65536;
  37. int wfifo_size = 65536;
  38. #ifndef TCP_FRAME_LEN
  39. #define TCP_FRAME_LEN 1053
  40. #endif
  41. struct socket_data *session[FD_SETSIZE];
  42. static int null_parse(int fd);
  43. static int (*default_func_parse)(int) = null_parse;
  44. static int null_console_parse(char *buf);
  45. static int (*default_console_parse)(char*) = null_console_parse;
  46. /*======================================
  47. * CORE : Set function
  48. *--------------------------------------
  49. */
  50. void set_defaultparse(int (*defaultparse)(int))
  51. {
  52. default_func_parse = defaultparse;
  53. }
  54. void set_nonblocking(int fd, int yes) {
  55. setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,(char *)&yes,sizeof yes);
  56. }
  57. static void setsocketopts(int fd)
  58. {
  59. int yes = 1; // reuse fix
  60. setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof yes);
  61. #ifdef SO_REUSEPORT
  62. setsockopt(fd,SOL_SOCKET,SO_REUSEPORT,(char *)&yes,sizeof yes);
  63. #endif
  64. set_nonblocking(fd, yes);
  65. setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &wfifo_size , sizeof(rfifo_size ));
  66. setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &rfifo_size , sizeof(rfifo_size ));
  67. }
  68. /*======================================
  69. * CORE : Socket Sub Function
  70. *--------------------------------------
  71. */
  72. static int recv_to_fifo(int fd)
  73. {
  74. int len;
  75. //printf("recv_to_fifo : %d %d\n",fd,session[fd]->eof);
  76. if(session[fd]->eof)
  77. return -1;
  78. #ifdef _WIN32
  79. len=recv(fd,session[fd]->rdata+session[fd]->rdata_size, RFIFOSPACE(fd), 0);
  80. #else
  81. len=read(fd,session[fd]->rdata+session[fd]->rdata_size,RFIFOSPACE(fd));
  82. #endif
  83. // printf (":::RECEIVE:::\n");
  84. // dump(session[fd]->rdata, len); printf ("\n");
  85. //{ int i; printf("recv %d : ",fd); for(i=0;i<len;i++){ printf("%02x ",RFIFOB(fd,session[fd]->rdata_size+i)); } printf("\n");}
  86. if(len>0){
  87. session[fd]->rdata_size+=len;
  88. session[fd]->rdata_tick = tick_;
  89. } else if(len<=0){
  90. // value of connection is not necessary the same
  91. // printf("set eof : connection #%d\n", fd);
  92. session[fd]->eof=1;
  93. }
  94. return 0;
  95. }
  96. static int send_from_fifo(int fd)
  97. {
  98. int len;
  99. //printf("send_from_fifo : %d\n",fd);
  100. if(session[fd]->eof || session[fd]->wdata == 0)
  101. return -1;
  102. if (session[fd]->wdata_size == 0)
  103. return 0;
  104. #ifdef _WIN32
  105. len=send(fd, session[fd]->wdata,session[fd]->wdata_size, 0);
  106. #else
  107. len=write(fd,session[fd]->wdata,session[fd]->wdata_size);
  108. #endif
  109. // printf (":::SEND:::\n");
  110. // dump(session[fd]->wdata, len); printf ("\n");
  111. //{ int i; printf("send %d : ",fd); for(i=0;i<len;i++){ printf("%02x ",session[fd]->wdata[i]); } printf("\n");}
  112. if(len>0){
  113. if(len<session[fd]->wdata_size){
  114. memmove(session[fd]->wdata,session[fd]->wdata+len,session[fd]->wdata_size-len);
  115. session[fd]->wdata_size-=len;
  116. } else {
  117. session[fd]->wdata_size=0;
  118. }
  119. } else if (errno != EAGAIN) {
  120. // printf("set eof :%d\n",fd);
  121. session[fd]->eof=1;
  122. }
  123. return 0;
  124. }
  125. void flush_fifos()
  126. {
  127. int i;
  128. for(i=0;i<fd_max;i++)
  129. if(session[i] != NULL &&
  130. session[i]->func_send == send_from_fifo)
  131. send_from_fifo(i);
  132. }
  133. static int null_parse(int fd)
  134. {
  135. printf("null_parse : %d\n",fd);
  136. RFIFOSKIP(fd,RFIFOREST(fd));
  137. return 0;
  138. }
  139. /*======================================
  140. * CORE : Socket Function
  141. *--------------------------------------
  142. */
  143. static int connect_client(int listen_fd)
  144. {
  145. int fd;
  146. struct sockaddr_in client_address;
  147. int len;
  148. #ifndef _WIN32
  149. int result;
  150. #endif
  151. //printf("connect_client : %d\n",listen_fd);
  152. len=sizeof(client_address);
  153. fd = accept(listen_fd,(struct sockaddr*)&client_address,(socklen_t*)&len);
  154. if(fd_max<=fd) fd_max=fd+1;
  155. setsocketopts(fd);
  156. if(fd==-1)
  157. perror("accept");
  158. else
  159. FD_SET(fd,&readfds);
  160. #ifdef _WIN32
  161. {
  162. unsigned long val = 1;
  163. ioctlsocket(fd, FIONBIO, &val);
  164. }
  165. #else
  166. result = fcntl(fd, F_SETFL, O_NONBLOCK);
  167. #endif
  168. CREATE(session[fd], struct socket_data, 1);
  169. CREATE_A(session[fd]->rdata, unsigned char, rfifo_size);
  170. CREATE_A(session[fd]->wdata, unsigned char, wfifo_size);
  171. session[fd]->max_rdata = rfifo_size;
  172. session[fd]->max_wdata = wfifo_size;
  173. session[fd]->func_recv = recv_to_fifo;
  174. session[fd]->func_send = send_from_fifo;
  175. session[fd]->func_parse = default_func_parse;
  176. session[fd]->client_addr = client_address;
  177. session[fd]->rdata_tick = tick_;
  178. //printf("new_session : %d %d\n",fd,session[fd]->eof);
  179. return fd;
  180. }
  181. int make_listen_port(int port)
  182. {
  183. struct sockaddr_in server_address;
  184. int fd;
  185. int result;
  186. fd = socket( AF_INET, SOCK_STREAM, 0 );
  187. if(fd_max<=fd) fd_max=fd+1;
  188. #ifdef _WIN32
  189. {
  190. unsigned long val = 1;
  191. ioctlsocket(fd, FIONBIO, &val);
  192. }
  193. #else
  194. result = fcntl(fd, F_SETFL, O_NONBLOCK);
  195. #endif
  196. setsocketopts(fd);
  197. server_address.sin_family = AF_INET;
  198. server_address.sin_addr.s_addr = htonl( INADDR_ANY );
  199. server_address.sin_port = htons((unsigned short)port);
  200. result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
  201. if( result == -1 ) {
  202. perror("bind");
  203. exit(1);
  204. }
  205. result = listen( fd, 5 );
  206. if( result == -1 ) { /* error */
  207. perror("listen");
  208. exit(1);
  209. }
  210. FD_SET(fd, &readfds );
  211. CREATE(session[fd], struct socket_data, 1);
  212. if(session[fd]==NULL){
  213. printf("out of memory : make_listen_port\n");
  214. exit(1);
  215. }
  216. memset(session[fd],0,sizeof(*session[fd]));
  217. session[fd]->func_recv = connect_client;
  218. return fd;
  219. }
  220. int make_listen_bind(long ip,int port)
  221. {
  222. struct sockaddr_in server_address;
  223. int fd;
  224. int result;
  225. fd = socket( AF_INET, SOCK_STREAM, 0 );
  226. if(fd_max<=fd) fd_max=fd+1;
  227. #ifdef _WIN32
  228. {
  229. unsigned long val = 1;
  230. ioctlsocket(fd, FIONBIO, &val);
  231. }
  232. #else
  233. result = fcntl(fd, F_SETFL, O_NONBLOCK);
  234. #endif
  235. setsocketopts(fd);
  236. server_address.sin_family = AF_INET;
  237. server_address.sin_addr.s_addr = ip;
  238. server_address.sin_port = htons((unsigned short)port);
  239. result = bind(fd, (struct sockaddr*)&server_address, sizeof(server_address));
  240. if( result == -1 ) {
  241. perror("bind");
  242. exit(1);
  243. }
  244. result = listen( fd, 5 );
  245. if( result == -1 ) { /* error */
  246. perror("listen");
  247. exit(1);
  248. }
  249. FD_SET(fd, &readfds );
  250. CREATE(session[fd], struct socket_data, 1);
  251. if(session[fd]==NULL){
  252. printf("out of memory : make_listen_bind\n");
  253. exit(1);
  254. }
  255. memset(session[fd],0,sizeof(*session[fd]));
  256. session[fd]->func_recv = connect_client;
  257. return fd;
  258. }
  259. // Console Reciever [Wizputer]
  260. int console_recieve(int i) {
  261. int n;
  262. char *buf;
  263. CREATE_A(buf, char , 64);
  264. memset(buf,0,sizeof(64));
  265. n = read(0, buf , 64);
  266. if ( n < 0 )
  267. printf("Console input read error\n");
  268. else
  269. session[0]->func_console(buf);
  270. return 0;
  271. }
  272. void set_defaultconsoleparse(int (*defaultparse)(char*))
  273. {
  274. default_console_parse = defaultparse;
  275. }
  276. static int null_console_parse(char *buf)
  277. {
  278. printf("null_console_parse : %s\n",buf);
  279. return 0;
  280. }
  281. // Console Input [Wizputer]
  282. int start_console(void) {
  283. FD_SET(0,&readfds);
  284. CREATE(session[0], struct socket_data, 1);
  285. if(session[0]==NULL){
  286. printf("out of memory : start_console\n");
  287. exit(1);
  288. }
  289. memset(session[0],0,sizeof(*session[0]));
  290. session[0]->func_recv = console_recieve;
  291. session[0]->func_console = default_console_parse;
  292. return 0;
  293. }
  294. int make_connection(long ip,int port)
  295. {
  296. struct sockaddr_in server_address;
  297. int fd;
  298. int result;
  299. fd = socket( AF_INET, SOCK_STREAM, 0 );
  300. if(fd_max<=fd)
  301. fd_max=fd+1;
  302. setsocketopts(fd);
  303. server_address.sin_family = AF_INET;
  304. server_address.sin_addr.s_addr = ip;
  305. server_address.sin_port = htons((unsigned short)port);
  306. #ifdef _WIN32
  307. {
  308. unsigned long val = 1;
  309. ioctlsocket(fd, FIONBIO, &val);
  310. }
  311. #else
  312. result = fcntl(fd, F_SETFL, O_NONBLOCK);
  313. #endif
  314. result = connect(fd, (struct sockaddr *)(&server_address),sizeof(struct sockaddr_in));
  315. FD_SET(fd,&readfds);
  316. CREATE(session[fd], struct socket_data, 1);
  317. CREATE_A(session[fd]->rdata, unsigned char, rfifo_size);
  318. CREATE_A(session[fd]->wdata, unsigned char, wfifo_size);
  319. session[fd]->max_rdata = rfifo_size;
  320. session[fd]->max_wdata = wfifo_size;
  321. session[fd]->func_recv = recv_to_fifo;
  322. session[fd]->func_send = send_from_fifo;
  323. session[fd]->func_parse = default_func_parse;
  324. session[fd]->rdata_tick = tick_;
  325. return fd;
  326. }
  327. int delete_session(int fd)
  328. {
  329. if(fd<0 || fd>=FD_SETSIZE)
  330. return -1;
  331. FD_CLR(fd,&readfds);
  332. if(session[fd]){
  333. if(session[fd]->rdata)
  334. aFree(session[fd]->rdata);
  335. if(session[fd]->wdata)
  336. aFree(session[fd]->wdata);
  337. if(session[fd]->session_data)
  338. aFree(session[fd]->session_data);
  339. aFree(session[fd]);
  340. }
  341. session[fd]=NULL;
  342. //printf("delete_session:%d\n",fd);
  343. return 0;
  344. }
  345. int realloc_fifo(int fd,int rfifo_size,int wfifo_size)
  346. {
  347. struct socket_data *s=session[fd];
  348. if( s->max_rdata != rfifo_size && s->rdata_size < rfifo_size){
  349. RECREATE(s->rdata, unsigned char, rfifo_size);
  350. s->max_rdata = rfifo_size;
  351. }
  352. if( s->max_wdata != wfifo_size && s->wdata_size < wfifo_size){
  353. RECREATE(s->wdata, unsigned char, wfifo_size);
  354. s->max_wdata = wfifo_size;
  355. }
  356. return 0;
  357. }
  358. int WFIFOSET(int fd,int len)
  359. {
  360. struct socket_data *s=session[fd];
  361. if (s == NULL || s->wdata == NULL)
  362. return 0;
  363. if( s->wdata_size+len+16384 > s->max_wdata ){
  364. unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
  365. realloc_fifo(fd,s->max_rdata, s->max_wdata <<1 );
  366. printf("socket: %d (%d.%d.%d.%d) wdata expanded to %d bytes.\n",fd, sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], s->max_wdata);
  367. }
  368. s->wdata_size=(s->wdata_size+(len)+2048 < s->max_wdata) ?
  369. s->wdata_size+len : (printf("socket: %d wdata lost !!\n",fd),s->wdata_size);
  370. if (s->wdata_size > (TCP_FRAME_LEN))
  371. send_from_fifo(fd);
  372. return 0;
  373. }
  374. int do_sendrecv(int next)
  375. {
  376. fd_set rfd,wfd;
  377. struct timeval timeout;
  378. int ret,i;
  379. tick_ = time(0);
  380. memcpy(&rfd, &readfds, sizeof(rfd));
  381. FD_ZERO(&wfd);
  382. for(i=0;i<fd_max;i++){
  383. if(!session[i] && FD_ISSET(i,&readfds)){
  384. printf("force clr fds %d\n",i);
  385. FD_CLR(i,&readfds);
  386. continue;
  387. }
  388. if(!session[i])
  389. continue;
  390. if(session[i]->wdata_size)
  391. FD_SET(i,&wfd);
  392. }
  393. timeout.tv_sec = next/1000;
  394. timeout.tv_usec = next%1000*1000;
  395. ret = select(fd_max,&rfd,&wfd,NULL,&timeout);
  396. if(ret<=0)
  397. return 0;
  398. for(i=0;i<fd_max;i++){
  399. if(!session[i])
  400. continue;
  401. if(FD_ISSET(i,&wfd)){
  402. //printf("write:%d\n",i);
  403. if(session[i]->func_send)
  404. session[i]->func_send(i);
  405. }
  406. if(FD_ISSET(i,&rfd)){
  407. //printf("read:%d\n",i);
  408. if(session[i]->func_recv)
  409. session[i]->func_recv(i);
  410. }
  411. }
  412. return 0;
  413. }
  414. int do_parsepacket(void)
  415. {
  416. int i;
  417. for(i=0;i<fd_max;i++){
  418. if(!session[i])
  419. continue;
  420. if ((session[i]->rdata_tick != 0) && ((tick_ - session[i]->rdata_tick) > stall_time_))
  421. session[i]->eof = 1;
  422. if(session[i]->rdata_size==0 && session[i]->eof==0)
  423. continue;
  424. if(session[i]->func_parse){
  425. session[i]->func_parse(i);
  426. if(!session[i])
  427. continue;
  428. }
  429. RFIFOFLUSH(i);
  430. }
  431. return 0;
  432. }
  433. void do_socket(void)
  434. {
  435. FD_ZERO(&readfds);
  436. }
  437. int RFIFOSKIP(int fd,int len)
  438. {
  439. struct socket_data *s=session[fd];
  440. if (s->rdata_size-s->rdata_pos-len<0) {
  441. fprintf(stderr,"too many skip\n");
  442. exit(1);
  443. }
  444. s->rdata_pos = s->rdata_pos+len;
  445. return 0;
  446. }
  447. unsigned int addr_[16]; // ip addresses of local host (host byte order)
  448. unsigned int naddr_ = 0; // # of ip addresses
  449. int Net_Init(void)
  450. {
  451. #ifdef _WIN32
  452. char** a;
  453. unsigned int i;
  454. char fullhost[255];
  455. struct hostent* hent;
  456. /* Start up the windows networking */
  457. WSADATA wsaData;
  458. if ( WSAStartup(WINSOCK_VERSION, &wsaData) != 0 ) {
  459. printf("SYSERR: WinSock not available!\n");
  460. exit(1);
  461. }
  462. if(gethostname(fullhost, sizeof(fullhost)) == SOCKET_ERROR) {
  463. printf("Ugg.. no hostname defined!\n");
  464. return 0;
  465. }
  466. // XXX This should look up the local IP addresses in the registry
  467. // instead of calling gethostbyname. However, the way IP addresses
  468. // are stored in the registry is annoyingly complex, so I'll leave
  469. // this as T.B.D.
  470. hent = gethostbyname(fullhost);
  471. if (hent == NULL) {
  472. printf("Cannot resolve our own hostname to a IP address");
  473. return 0;
  474. }
  475. a = hent->h_addr_list;
  476. for(i = 0; a[i] != 0 && i < 16; ++i) {
  477. unsigned long addr1 = ntohl(*(unsigned long*) a[i]);
  478. addr_[i] = addr1;
  479. }
  480. naddr_ = i;
  481. #else
  482. int pos;
  483. int fdes = socket(AF_INET, SOCK_STREAM, 0);
  484. char buf[16 * sizeof(struct ifreq)];
  485. struct ifconf ic;
  486. // The ioctl call will fail with Invalid Argument if there are more
  487. // interfaces than will fit in the buffer
  488. ic.ifc_len = sizeof(buf);
  489. ic.ifc_buf = buf;
  490. if(ioctl(fdes, SIOCGIFCONF, &ic) == -1) {
  491. printf("SIOCGIFCONF failed!\n");
  492. return 0;
  493. }
  494. for(pos = 0; pos < ic.ifc_len;)
  495. {
  496. struct ifreq * ir = (struct ifreq *) (ic.ifc_buf + pos);
  497. struct sockaddr_in * a = (struct sockaddr_in *) &(ir->ifr_addr);
  498. if(a->sin_family == AF_INET) {
  499. u_long ad = ntohl(a->sin_addr.s_addr);
  500. if(ad != INADDR_LOOPBACK) {
  501. addr_[naddr_ ++] = ad;
  502. if(naddr_ == 16)
  503. break;
  504. }
  505. }
  506. #if defined(_AIX) || defined(__APPLE__)
  507. pos += ir->ifr_addr.sa_len; // For when we port athena to run on Mac's :)
  508. pos += sizeof(ir->ifr_name);
  509. #else
  510. pos += sizeof(struct ifreq);
  511. #endif
  512. }
  513. #endif
  514. return(0);
  515. }