socket.c 12 KB

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