You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

552 lines
13 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007,2008 Øyvind Harboe *
  6. * oyvind.harboe@zylin.com *
  7. * *
  8. * Copyright (C) 2008 by Spencer Oliver *
  9. * spen@spen-soft.co.uk *
  10. * *
  11. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. * This program is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  19. * GNU General Public License for more details. *
  20. * *
  21. * You should have received a copy of the GNU General Public License *
  22. * along with this program; if not, write to the *
  23. * Free Software Foundation, Inc., *
  24. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  25. ***************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include "server.h"
  30. #include "target.h"
  31. #include <signal.h>
  32. #ifndef _WIN32
  33. #include <netinet/tcp.h>
  34. #endif
  35. service_t *services = NULL;
  36. /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
  37. static int shutdown_openocd = 0;
  38. int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  39. /* set when using pipes rather than tcp */
  40. int server_use_pipes = 0;
  41. int add_connection(service_t *service, command_context_t *cmd_ctx)
  42. {
  43. socklen_t address_size;
  44. connection_t *c, **p;
  45. int retval;
  46. int flag=1;
  47. c = malloc(sizeof(connection_t));
  48. c->fd = -1;
  49. memset(&c->sin, 0, sizeof(c->sin));
  50. c->cmd_ctx = copy_command_context(cmd_ctx);
  51. c->service = service;
  52. c->input_pending = 0;
  53. c->priv = NULL;
  54. c->next = NULL;
  55. if (service->type == CONNECTION_TCP)
  56. {
  57. address_size = sizeof(c->sin);
  58. c->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
  59. /* This increases performance dramatically for e.g. GDB load which
  60. * does not have a sliding window protocol. */
  61. retval=setsockopt(c->fd, /* socket affected */
  62. IPPROTO_TCP, /* set option at TCP level */
  63. TCP_NODELAY, /* name of option */
  64. (char *)&flag, /* the cast is historical cruft */
  65. sizeof(int)); /* length of option value */
  66. LOG_INFO("accepting '%s' connection from %i", service->name, c->sin.sin_port);
  67. if ((retval = service->new_connection(c)) != ERROR_OK)
  68. {
  69. close_socket(c->fd);
  70. LOG_ERROR("attempted '%s' connection rejected", service->name);
  71. free(c);
  72. return retval;
  73. }
  74. }
  75. else if (service->type == CONNECTION_PIPE)
  76. {
  77. c->fd = service->fd;
  78. /* do not check for new connections again on stdin */
  79. service->fd = -1;
  80. LOG_INFO("accepting '%s' connection from pipe", service->name);
  81. if ((retval = service->new_connection(c)) != ERROR_OK)
  82. {
  83. LOG_ERROR("attempted '%s' connection rejected", service->name);
  84. free(c);
  85. return retval;
  86. }
  87. }
  88. /* add to the end of linked list */
  89. for (p = &service->connections; *p; p = &(*p)->next);
  90. *p = c;
  91. service->max_connections--;
  92. return ERROR_OK;
  93. }
  94. int remove_connection(service_t *service, connection_t *connection)
  95. {
  96. connection_t **p = &service->connections;
  97. connection_t *c;
  98. /* find connection */
  99. while ((c = *p))
  100. {
  101. if (c->fd == connection->fd)
  102. {
  103. service->connection_closed(c);
  104. if (service->type == CONNECTION_TCP)
  105. close_socket(c->fd);
  106. command_done(c->cmd_ctx);
  107. /* delete connection */
  108. *p = c->next;
  109. free(c);
  110. service->max_connections++;
  111. break;
  112. }
  113. /* redirect p to next list pointer */
  114. p = &(*p)->next;
  115. }
  116. return ERROR_OK;
  117. }
  118. int add_service(char *name, enum connection_type type, unsigned short port, int max_connections, new_connection_handler_t new_connection_handler, input_handler_t input_handler, connection_closed_handler_t connection_closed_handler, void *priv)
  119. {
  120. service_t *c, **p;
  121. int so_reuseaddr_option = 1;
  122. c = malloc(sizeof(service_t));
  123. c->name = strdup(name);
  124. c->type = type;
  125. c->port = port;
  126. c->max_connections = max_connections;
  127. c->fd = -1;
  128. c->connections = NULL;
  129. c->new_connection = new_connection_handler;
  130. c->input = input_handler;
  131. c->connection_closed = connection_closed_handler;
  132. c->priv = priv;
  133. c->next = NULL;
  134. if (type == CONNECTION_TCP)
  135. {
  136. if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  137. {
  138. LOG_ERROR("error creating socket: %s", strerror(errno));
  139. exit(-1);
  140. }
  141. setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&so_reuseaddr_option, sizeof(int));
  142. socket_nonblock(c->fd);
  143. memset(&c->sin, 0, sizeof(c->sin));
  144. c->sin.sin_family = AF_INET;
  145. c->sin.sin_addr.s_addr = INADDR_ANY;
  146. c->sin.sin_port = htons(port);
  147. if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1)
  148. {
  149. LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
  150. exit(-1);
  151. }
  152. #ifndef _WIN32
  153. int segsize=65536;
  154. setsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG, &segsize, sizeof(int));
  155. #endif
  156. int window_size = 128 * 1024;
  157. /* These setsockopt()s must happen before the listen() */
  158. setsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,
  159. (char *)&window_size, sizeof(window_size));
  160. setsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,
  161. (char *)&window_size, sizeof(window_size));
  162. if (listen(c->fd, 1) == -1)
  163. {
  164. LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
  165. exit(-1);
  166. }
  167. }
  168. else if (type == CONNECTION_PIPE)
  169. {
  170. /* use stdin */
  171. c->fd = STDIN_FILENO;
  172. #ifdef _WIN32
  173. /* for win32 set stdin/stdout to binary mode */
  174. if (_setmode(_fileno(stdout), _O_BINARY) < 0)
  175. LOG_WARNING("cannot change stdout mode to binary");
  176. if (_setmode(_fileno(stdin), _O_BINARY) < 0)
  177. LOG_WARNING("cannot change stdin mode to binary");
  178. if (_setmode(_fileno(stderr), _O_BINARY) < 0)
  179. LOG_WARNING("cannot change stderr mode to binary");
  180. #else
  181. socket_nonblock(c->fd);
  182. #endif
  183. }
  184. else
  185. {
  186. LOG_ERROR("unknown connection type: %d", type);
  187. exit(1);
  188. }
  189. /* add to the end of linked list */
  190. for (p = &services; *p; p = &(*p)->next);
  191. *p = c;
  192. return ERROR_OK;
  193. }
  194. int remove_service(unsigned short port)
  195. {
  196. service_t **p = &services;
  197. service_t *c;
  198. /* find service */
  199. while ((c = *p))
  200. {
  201. if (c->port == port)
  202. {
  203. if (c->name)
  204. free(c->name);
  205. if (c->priv)
  206. free(c->priv);
  207. /* delete service */
  208. *p = c->next;
  209. free(c);
  210. }
  211. /* redirect p to next list pointer */
  212. p = &(*p)->next;
  213. }
  214. return ERROR_OK;
  215. }
  216. int remove_services(void)
  217. {
  218. service_t *c = services;
  219. /* loop service */
  220. while (c)
  221. {
  222. service_t *next = c->next;
  223. if (c->name)
  224. free(c->name);
  225. if (c->priv)
  226. free(c->priv);
  227. /* delete service */
  228. free(c);
  229. /* remember the last service for unlinking */
  230. c = next;
  231. }
  232. services = NULL;
  233. return ERROR_OK;
  234. }
  235. extern void openocd_sleep_prelude(void);
  236. extern void openocd_sleep_postlude(void);
  237. int server_loop(command_context_t *command_context)
  238. {
  239. service_t *service;
  240. /* used in select() */
  241. fd_set read_fds;
  242. struct timeval tv;
  243. int fd_max;
  244. /* used in accept() */
  245. int retval;
  246. #ifndef _WIN32
  247. if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
  248. LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
  249. #endif
  250. /* do regular tasks after at most 10ms */
  251. tv.tv_sec = 0;
  252. tv.tv_usec = 10000;
  253. while (!shutdown_openocd)
  254. {
  255. /* monitor sockets for acitvity */
  256. fd_max = 0;
  257. FD_ZERO(&read_fds);
  258. /* add service and connection fds to read_fds */
  259. for (service = services; service; service = service->next)
  260. {
  261. if (service->fd != -1)
  262. {
  263. /* listen for new connections */
  264. FD_SET(service->fd, &read_fds);
  265. if (service->fd > fd_max)
  266. fd_max = service->fd;
  267. }
  268. if (service->connections)
  269. {
  270. connection_t *c;
  271. for (c = service->connections; c; c = c->next)
  272. {
  273. /* check for activity on the connection */
  274. FD_SET(c->fd, &read_fds);
  275. if (c->fd > fd_max)
  276. fd_max = c->fd;
  277. }
  278. }
  279. }
  280. #ifndef _WIN32
  281. #if BUILD_ECOSBOARD == 0
  282. if (server_use_pipes == 0)
  283. {
  284. /* add STDIN to read_fds */
  285. FD_SET(fileno(stdin), &read_fds);
  286. }
  287. #endif
  288. #endif
  289. openocd_sleep_prelude();
  290. kept_alive();
  291. /* Only while we're sleeping we'll let others run */
  292. retval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);
  293. openocd_sleep_postlude();
  294. if (retval == -1)
  295. {
  296. #ifdef _WIN32
  297. errno = WSAGetLastError();
  298. if (errno == WSAEINTR)
  299. FD_ZERO(&read_fds);
  300. else
  301. {
  302. LOG_ERROR("error during select: %s", strerror(errno));
  303. exit(-1);
  304. }
  305. #else
  306. if (errno == EINTR)
  307. {
  308. FD_ZERO(&read_fds);
  309. }
  310. else
  311. {
  312. LOG_ERROR("error during select: %s", strerror(errno));
  313. exit(-1);
  314. }
  315. #endif
  316. }
  317. target_call_timer_callbacks();
  318. process_jim_events ();
  319. if (retval == 0)
  320. {
  321. /* do regular tasks after at most 100ms */
  322. tv.tv_sec = 0;
  323. tv.tv_usec = 10000;
  324. FD_ZERO(&read_fds); /* eCos leaves read_fds unchanged in this case! */
  325. }
  326. for (service = services; service; service = service->next)
  327. {
  328. /* handle new connections on listeners */
  329. if ((service->fd != -1)
  330. && (FD_ISSET(service->fd, &read_fds)))
  331. {
  332. if (service->max_connections > 0)
  333. {
  334. add_connection(service, command_context);
  335. }
  336. else
  337. {
  338. if (service->type != CONNECTION_PIPE)
  339. {
  340. struct sockaddr_in sin;
  341. socklen_t address_size = sizeof(sin);
  342. int tmp_fd;
  343. tmp_fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);
  344. close_socket(tmp_fd);
  345. }
  346. LOG_INFO("rejected '%s' connection, no more connections allowed", service->name);
  347. }
  348. }
  349. /* handle activity on connections */
  350. if (service->connections)
  351. {
  352. connection_t *c;
  353. for (c = service->connections; c;)
  354. {
  355. if ((FD_ISSET(c->fd, &read_fds)) || c->input_pending)
  356. {
  357. if ((retval = service->input(c)) != ERROR_OK)
  358. {
  359. connection_t *next = c->next;
  360. if (service->type == CONNECTION_PIPE)
  361. {
  362. /* if connection uses a pipe then shutdown openocd on error */
  363. shutdown_openocd = 1;
  364. }
  365. remove_connection(service, c);
  366. LOG_INFO("dropped '%s' connection - error %d", service->name, retval);
  367. c = next;
  368. continue;
  369. }
  370. }
  371. c = c->next;
  372. }
  373. }
  374. }
  375. #ifndef _WIN32
  376. #if BUILD_ECOSBOARD == 0
  377. /* check for data on stdin if not using pipes */
  378. if (server_use_pipes == 0)
  379. {
  380. if (FD_ISSET(fileno(stdin), &read_fds))
  381. {
  382. if (getc(stdin) == 'x')
  383. {
  384. shutdown_openocd = 1;
  385. }
  386. }
  387. }
  388. #endif
  389. #else
  390. MSG msg;
  391. while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  392. {
  393. if (msg.message == WM_QUIT)
  394. shutdown_openocd = 1;
  395. }
  396. #endif
  397. }
  398. return ERROR_OK;
  399. }
  400. #ifdef _WIN32
  401. BOOL WINAPI ControlHandler(DWORD dwCtrlType)
  402. {
  403. shutdown_openocd = 1;
  404. return TRUE;
  405. }
  406. void sig_handler(int sig) {
  407. shutdown_openocd = 1;
  408. }
  409. #endif
  410. int server_init(void)
  411. {
  412. #ifdef _WIN32
  413. WORD wVersionRequested;
  414. WSADATA wsaData;
  415. wVersionRequested = MAKEWORD(2, 2);
  416. if (WSAStartup(wVersionRequested, &wsaData) != 0)
  417. {
  418. LOG_ERROR("Failed to Open Winsock");
  419. exit(-1);
  420. }
  421. if (server_use_pipes == 0)
  422. {
  423. /* register ctrl-c handler */
  424. SetConsoleCtrlHandler(ControlHandler, TRUE);
  425. }
  426. else
  427. {
  428. /* we are using pipes so ignore ctrl-c */
  429. SetConsoleCtrlHandler(NULL, TRUE);
  430. }
  431. signal(SIGINT, sig_handler);
  432. signal(SIGTERM, sig_handler);
  433. signal(SIGBREAK, sig_handler);
  434. signal(SIGABRT, sig_handler);
  435. #endif
  436. return ERROR_OK;
  437. }
  438. int server_quit(void)
  439. {
  440. remove_services();
  441. #ifdef _WIN32
  442. WSACleanup();
  443. SetConsoleCtrlHandler( ControlHandler, FALSE );
  444. #endif
  445. return ERROR_OK;
  446. }
  447. int server_register_commands(command_context_t *context)
  448. {
  449. register_command(context, NULL, "shutdown", handle_shutdown_command,
  450. COMMAND_ANY, "shut the server down");
  451. return ERROR_OK;
  452. }
  453. /* tell the server we want to shut down */
  454. int handle_shutdown_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  455. {
  456. shutdown_openocd = 1;
  457. return ERROR_COMMAND_CLOSE_CONNECTION;
  458. }