net.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 2000,2001 Onlyer (onlyer@263.net)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #include "common/setup_before.h"
  19. #include "setup.h"
  20. #ifdef HAVE_STDDEF_H
  21. # include <stddef.h>
  22. #else
  23. # ifndef NULL
  24. #  define NULL ((void *)0)
  25. # endif
  26. #endif
  27. #include <ctype.h>
  28. #ifdef HAVE_STRING_H
  29. # include <string.h>
  30. #else
  31. # ifdef HAVE_STRINGS_H
  32. #  include <strings.h>
  33. # endif
  34. # ifdef HAVE_MEMORY_H
  35. #  include <memory.h>
  36. # endif
  37. #endif
  38. #ifdef STDC_HEADERS
  39. # include <stdlib.h>
  40. #else
  41. # ifdef HAVE_MALLOC_H
  42. #  include <malloc.h>
  43. # endif
  44. #endif
  45. #include "compat/memset.h"
  46. #include <errno.h>
  47. #include "compat/strerror.h"
  48. #ifdef HAVE_UNISTD_H
  49. # include <unistd.h>
  50. #endif
  51. #ifdef HAVE_FCNTL_H
  52. # include <fcntl.h>
  53. #else
  54. # ifdef HAVE_SYS_FILE_H
  55. #  include <sys/file.h>
  56. # endif
  57. #endif
  58. #ifdef HAVE_SYS_TYPES_H
  59. # include <sys/types.h>
  60. #endif
  61. #ifdef HAVE_SYS_SOCKET_H
  62. # include <sys/socket.h>
  63. #endif
  64. #include "compat/socket.h"
  65. #ifdef HAVE_SYS_PARAM_H
  66. # include <sys/param.h>
  67. #endif
  68. #ifdef HAVE_NETINET_IN_H
  69. # include <netinet/in.h>
  70. #endif
  71. #include "compat/netinet_in.h"
  72. #ifdef HAVE_ARPA_INET_H
  73. # include <arpa/inet.h>
  74. #endif
  75. #ifdef HAVE_NETDB_H
  76. # include <netdb.h>
  77. #endif
  78. #include "compat/psock.h"
  79. #include "net.h"
  80. #include "common/eventlog.h"
  81. #include "common/setup_after.h"
  82. /* FIXME: use addr.h code to do this and make a separate error
  83.  * return path so that 255.255.255.255 isn't an error.
  84.  */
  85. extern unsigned long int net_inet_addr(char const * host)
  86. {
  87. struct hostent * hp;
  88. if (isdigit(host[0])) {
  89. return inet_addr(host);
  90. } else {
  91. hp=gethostbyname(host);
  92. if (!hp || !(hp->h_addr_list)) {
  93. return ~0UL;
  94. }
  95. return *(unsigned long *)hp->h_addr_list[0];
  96. }
  97. }
  98. extern int net_socket(int type)
  99. {
  100. int sock;
  101. int val;
  102. int     ipproto;
  103. if (type==PSOCK_SOCK_STREAM) {
  104. ipproto = PSOCK_IPPROTO_TCP;
  105. } else {
  106. ipproto = PSOCK_IPPROTO_UDP;
  107. }
  108. if ((sock=psock_socket(PSOCK_PF_INET, type, ipproto))<0) {
  109. eventlog(eventlog_level_error,__FUNCTION__,"error creating socket (psock_socket: %s)", strerror(psock_errno()));
  110. return -1;
  111. }
  112. val=1;
  113. if (psock_setsockopt(sock,PSOCK_SOL_SOCKET, PSOCK_SO_KEEPALIVE, &val, sizeof(val))<0) {
  114. eventlog(eventlog_level_error,__FUNCTION__,"error set socket option KEEPALIVE (psock_setsockopt: %s)",strerror(psock_errno()));
  115. }
  116. if (psock_ctl(sock,PSOCK_NONBLOCK)<0) {
  117. eventlog(eventlog_level_error,__FUNCTION__,"error set socket mode to non-block (psock_ctl: %s)",strerror(psock_errno()));
  118. psock_close(sock);
  119. return -1;
  120. }
  121. return sock;
  122. }
  123. extern int net_check_connected(int sock)
  124. {
  125. int err;
  126. psock_t_socklen errlen;
  127. err = 0;
  128. errlen = sizeof(err);
  129. if (psock_getsockopt(sock,PSOCK_SOL_SOCKET, PSOCK_SO_ERROR, &err, &errlen)<0) {
  130. eventlog(eventlog_level_error,__FUNCTION__,"error get socket option SO_ERROR (psock_getsockopt: %s)",strerror(psock_errno()));
  131. return -1;
  132. }
  133. if (errlen && err)
  134.        return -1;
  135. return 0;
  136. }
  137. extern int net_listen(unsigned int ip, unsigned int port, int type)
  138. {
  139. int sock;
  140. int val;
  141. struct  sockaddr_in addr;
  142. int     ipproto;
  143. if (type==PSOCK_SOCK_STREAM) {
  144. ipproto = PSOCK_IPPROTO_TCP;
  145. } else {
  146. ipproto = PSOCK_IPPROTO_UDP;
  147. }
  148. if ((sock=psock_socket(PSOCK_PF_INET, type, ipproto))<0) {
  149. eventlog(eventlog_level_error,__FUNCTION__,"error create listen socket");
  150. return -1;
  151. }
  152. val=1;
  153. if (psock_setsockopt(sock,PSOCK_SOL_SOCKET,PSOCK_SO_REUSEADDR,&val,sizeof(int))<0) {
  154. eventlog(eventlog_level_error,__FUNCTION__,"error set socket option SO_REUSEADDR");
  155. }
  156. memset(&addr,0,sizeof(addr));
  157. addr.sin_family=PSOCK_AF_INET;
  158. addr.sin_port=htons(port);
  159. addr.sin_addr.s_addr=htonl(ip);
  160. if (psock_bind(sock,(struct sockaddr *)&addr, sizeof(addr))<0) {
  161. eventlog(eventlog_level_error,__FUNCTION__,"error bind listen socket");
  162. psock_close(sock);
  163. return -1;
  164. }
  165. if (psock_listen(sock,LISTEN_QUEUE)<0) {
  166. eventlog(eventlog_level_error,__FUNCTION__,"error listen socket");
  167. psock_close(sock);
  168. return -1;
  169. }
  170. return sock;
  171. }
  172. extern int net_send_data(int sock, char * buff, int buffsize, int * pos, int * currsize)
  173. {
  174. int nsend;
  175. ASSERT(buff,-1);
  176. ASSERT(pos,-1);
  177. if (*pos>buffsize) {
  178. eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer overflow pos=%d buffsize=%d",sock,*pos,buffsize);
  179. return -1;
  180. }
  181. if (*currsize>*pos) {
  182. eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer error currsize=%d pos=%d",sock,*currsize,*pos);
  183. return -1;
  184. }
  185. nsend=psock_send(sock,buff+*pos-*currsize,*currsize,0);
  186. if (nsend==0) {
  187. eventlog(eventlog_level_error,__FUNCTION__,"[%d] no data sent (close connection)",sock);
  188. return -1;
  189. }
  190. if (nsend<0) {
  191. if (
  192. #ifdef PSOCK_EINTR
  193. psock_errno()==PSOCK_EINTR ||
  194. #endif
  195. #ifdef PSOCK_EAGAIN
  196. psock_errno()==PSOCK_EAGAIN ||
  197. #endif
  198. #ifdef PSOCK_EWOULDBLOCK
  199. psock_errno()==PSOCK_EWOULDBLOCK ||
  200. #endif
  201. #ifdef PSOCK_NOBUFS
  202. psock_errno()==PSOCK_ENOBUFS ||
  203. #endif
  204. #ifdef PSOCK_ENOMEM
  205. psock_errno()==ENOMEM ||
  206. #endif
  207. 0)
  208. return 0;
  209. eventlog(eventlog_level_error,__FUNCTION__,"[%d] error sent data (closing connection) (psock_send: %s)",sock,strerror(psock_errno()));
  210. return -1;
  211. }
  212. *currsize -= nsend;
  213. return 1;
  214. }
  215. extern int net_recv_data(int sock, char * buff, int buffsize, int * pos, int * currsize)
  216. {
  217. int nrecv;
  218. ASSERT(buff,-1);
  219. ASSERT(pos,-1);
  220. if (*pos>buffsize) {
  221. eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv buffer overflow pos=%d buffsize=%d",sock,*pos,buffsize);
  222. return -1;
  223. }
  224. if (*currsize>*pos) {
  225. eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv buffer error currsize=%d pos=%d",sock,*currsize,*pos);
  226. return -1;
  227. }
  228. if (*pos==buffsize) {
  229. memmove(buff,buff+*pos,*currsize);
  230. *pos=0;
  231. }
  232. nrecv=psock_recv(sock,buff+*pos,buffsize-*pos,0);
  233. if (nrecv==0) {
  234. eventlog(eventlog_level_info,__FUNCTION__,"[%d] remote host closed connection",sock);
  235. return -1;
  236. if (nrecv<0) {
  237. if (
  238. #ifdef PSOCK_EINTR
  239. psock_errno()==PSOCK_EINTR ||
  240. #endif
  241. #ifdef PSOCK_EAGAIN
  242. psock_errno()==PSOCK_EAGAIN ||
  243. #endif
  244. #ifdef PSOCK_EWOULDBLOCK
  245. psock_errno()==PSOCK_EWOULDBLOCK ||
  246. #endif
  247. #ifdef PSOCK_ENOMEM
  248. psock_errno()==ENOMEM ||
  249. #endif
  250. 0)
  251. return 0;
  252. if ( 
  253. #ifdef PSOCK_ENOTCONN
  254. psock_errno()==PSOCK_ENOTCONN ||
  255. #endif
  256. #ifdef PSOCK_ECONNRESET
  257. psock_errno()==PSOCK_ECONNRESET ||
  258. #endif
  259. 0) {
  260. eventlog(eventlog_level_error,__FUNCTION__,"[%d] remote host closed connection (psock_recv: %s)",sock,strerror(psock_errno()));
  261. return -1;
  262. }
  263. eventlog(eventlog_level_error,__FUNCTION__,"[%d] recv error (closing connection) (psock_recv: %s)",sock,strerror(psock_errno()));
  264. return -1;
  265. }
  266. * currsize += nrecv;
  267. return 1;
  268. }