PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/user/inadyn/inadyn-1.98.1/src/tcp.c

https://bitbucket.org/altlc/wive-rtnl-ralink-rt305x-routers-firmware-amod
C | 311 lines | 209 code | 55 blank | 47 comment | 52 complexity | 3fcc1fb54f0059c308add1cd56629fe8 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-2.0, GPL-3.0, LGPL-3.0, 0BSD, AGPL-1.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. * Copyright (C) 2003-2004 Narcis Ilisei <inarcis2002@hotpop.com>
  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. #define MODULE_TAG ""
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include "debug_if.h"
  22. #include "tcp.h"
  23. /* basic resource allocations for the tcp object */
  24. RC_TYPE tcp_construct(TCP_SOCKET *p_self)
  25. {
  26. RC_TYPE rc;
  27. if (p_self == NULL)
  28. {
  29. return RC_INVALID_POINTER;
  30. }
  31. rc = ip_construct(&p_self->super);
  32. if (rc != RC_OK)
  33. {
  34. return rc;
  35. }
  36. /*reset its part of the struct (skip IP part)*/
  37. memset(((char*)p_self + sizeof(p_self->super)) , 0, sizeof(*p_self) - sizeof(p_self->super));
  38. p_self->initialized = FALSE;
  39. return RC_OK;
  40. }
  41. /*
  42. Resource free.
  43. */
  44. RC_TYPE tcp_destruct(TCP_SOCKET *p_self)
  45. {
  46. if (p_self == NULL)
  47. {
  48. return RC_OK;
  49. }
  50. if (p_self->initialized == TRUE)
  51. {
  52. tcp_shutdown(p_self);
  53. }
  54. return ip_destruct(&p_self->super);
  55. }
  56. static RC_TYPE local_set_params(TCP_SOCKET *p_self)
  57. {
  58. int timeout;
  59. /* Set default TCP specififc params */
  60. tcp_get_remote_timeout(p_self, &timeout);
  61. if (timeout == 0)
  62. {
  63. tcp_set_remote_timeout(p_self, TCP_DEFAULT_TIMEOUT);
  64. }
  65. return RC_OK;
  66. }
  67. /*
  68. Sets up the object.
  69. - ...
  70. */
  71. RC_TYPE tcp_initialize(TCP_SOCKET *p_self, char *msg)
  72. {
  73. RC_TYPE rc;
  74. struct timeval sv;
  75. int svlen = sizeof(sv);
  76. char host[NI_MAXHOST];
  77. do
  78. {
  79. local_set_params(p_self);
  80. /*call the super*/
  81. rc = ip_initialize(&p_self->super);
  82. if (rc != RC_OK)
  83. {
  84. break;
  85. }
  86. /* local object initalizations */
  87. if (p_self->super.type == TYPE_TCP)
  88. {
  89. p_self->super.socket = socket(AF_INET, SOCK_STREAM, 0);
  90. if (p_self->super.socket == -1)
  91. {
  92. int code = os_get_socket_error();
  93. logit(LOG_ERR, MODULE_TAG "Error creating client socket: %s", strerror(code));
  94. rc = RC_IP_SOCKET_CREATE_ERROR;
  95. break;
  96. }
  97. /* Call to socket() OK, allow tcp_shutdown() to run to
  98. * prevent socket leak if any of the below calls fail. */
  99. p_self->initialized = TRUE;
  100. if (p_self->super.bound == TRUE)
  101. {
  102. if (bind(p_self->super.socket, (struct sockaddr *)&p_self->super.local_addr, sizeof(struct sockaddr_in)) < 0)
  103. {
  104. int code = os_get_socket_error();
  105. logit(LOG_WARNING, MODULE_TAG "Failed binding client socket to local address: %s", strerror(code));
  106. rc = RC_IP_SOCKET_BIND_ERROR;
  107. break;
  108. }
  109. }
  110. }
  111. else
  112. {
  113. p_self->initialized = TRUE; /* Allow tcp_shutdown() to run. */
  114. rc = RC_IP_BAD_PARAMETER;
  115. }
  116. /* set timeouts */
  117. sv.tv_sec = p_self->super.timeout / 1000; /* msec to sec */
  118. sv.tv_usec = (p_self->super.timeout % 1000) * 1000; /* reminder to usec */
  119. setsockopt(p_self->super.socket, SOL_SOCKET, SO_RCVTIMEO, &sv, svlen);
  120. setsockopt(p_self->super.socket, SOL_SOCKET, SO_SNDTIMEO, &sv, svlen);
  121. if (!getnameinfo(&p_self->super.remote_addr, p_self->super.remote_len, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST))
  122. {
  123. logit(LOG_INFO, "%s, connecting to %s(%s)", msg, p_self->super.p_remote_host_name, host);
  124. }
  125. if (0 != connect(p_self->super.socket, &p_self->super.remote_addr, p_self->super.remote_len))
  126. {
  127. int code = os_get_socket_error();
  128. logit(LOG_WARNING, MODULE_TAG "Failed connecting to remote server: %s", strerror(code));
  129. rc = RC_IP_CONNECT_FAILED;
  130. break;
  131. }
  132. }
  133. while (0);
  134. if (rc != RC_OK)
  135. {
  136. tcp_shutdown(p_self);
  137. return rc;
  138. }
  139. return RC_OK;
  140. }
  141. /*
  142. Disconnect and some other clean up.
  143. */
  144. RC_TYPE tcp_shutdown(TCP_SOCKET *p_self)
  145. {
  146. if (p_self == NULL)
  147. {
  148. return RC_INVALID_POINTER;
  149. }
  150. if (!p_self->initialized)
  151. {
  152. return RC_OK;
  153. }
  154. p_self->initialized = FALSE;
  155. return ip_shutdown(&p_self->super);
  156. }
  157. /* send data*/
  158. RC_TYPE tcp_send(TCP_SOCKET *p_self, const char *p_buf, int len)
  159. {
  160. if (p_self == NULL)
  161. {
  162. return RC_INVALID_POINTER;
  163. }
  164. if (!p_self->initialized)
  165. {
  166. return RC_TCP_OBJECT_NOT_INITIALIZED;
  167. }
  168. return ip_send(&p_self->super, p_buf, len);
  169. }
  170. /* receive data*/
  171. RC_TYPE tcp_recv(TCP_SOCKET *p_self,char *p_buf, int max_recv_len, int *p_recv_len)
  172. {
  173. if (p_self == NULL)
  174. {
  175. return RC_INVALID_POINTER;
  176. }
  177. if (!p_self->initialized)
  178. {
  179. return RC_TCP_OBJECT_NOT_INITIALIZED;
  180. }
  181. return ip_recv(&p_self->super, p_buf, max_recv_len, p_recv_len);
  182. }
  183. /* Accessors*/
  184. RC_TYPE tcp_set_port(TCP_SOCKET *p_self, int p)
  185. {
  186. if (p_self == NULL)
  187. {
  188. return RC_INVALID_POINTER;
  189. }
  190. return ip_set_port(&p_self->super, p);
  191. }
  192. RC_TYPE tcp_set_remote_name(TCP_SOCKET *p_self, const char* p)
  193. {
  194. if (p_self == NULL)
  195. {
  196. return RC_INVALID_POINTER;
  197. }
  198. return ip_set_remote_name(&p_self->super, p);
  199. }
  200. RC_TYPE tcp_set_remote_timeout(TCP_SOCKET *p_self, int p)
  201. {
  202. if (p_self == NULL)
  203. {
  204. return RC_INVALID_POINTER;
  205. }
  206. return ip_set_remote_timeout(&p_self->super, p);
  207. }
  208. RC_TYPE tcp_set_bind_iface(TCP_SOCKET *p_self, char *ifname)
  209. {
  210. if (p_self == NULL)
  211. {
  212. return RC_INVALID_POINTER;
  213. }
  214. return ip_set_bind_iface(&p_self->super, ifname);
  215. }
  216. RC_TYPE tcp_get_port(TCP_SOCKET *p_self, int *p)
  217. {
  218. if (p_self == NULL)
  219. {
  220. return RC_INVALID_POINTER;
  221. }
  222. return ip_get_port(&p_self->super, p);
  223. }
  224. RC_TYPE tcp_get_remote_name(TCP_SOCKET *p_self, const char **p)
  225. {
  226. if (p_self == NULL)
  227. {
  228. return RC_INVALID_POINTER;
  229. }
  230. return ip_get_remote_name(&p_self->super, p);
  231. }
  232. RC_TYPE tcp_get_remote_timeout(TCP_SOCKET *p_self, int *p)
  233. {
  234. if (p_self == NULL)
  235. {
  236. return RC_INVALID_POINTER;
  237. }
  238. return ip_get_remote_timeout(&p_self->super, p);
  239. }
  240. RC_TYPE tcp_get_bind_iface(TCP_SOCKET *p_self, char **ifname)
  241. {
  242. if (p_self == NULL || ifname == NULL)
  243. {
  244. return RC_INVALID_POINTER;
  245. }
  246. return ip_get_bind_iface(&p_self->super, ifname);
  247. }
  248. /**
  249. * Local Variables:
  250. * version-control: t
  251. * indent-tabs-mode: t
  252. * c-file-style: "ellemtel"
  253. * c-basic-offset: 8
  254. * End:
  255. */