1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2007,2008 Øyvind Harboe *
6 * oyvind.harboe@zylin.com *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
32 #include "telnet_server.h"
40 #include <sys/types.h>
44 #include <netinet/tcp.h>
47 service_t
*services
= NULL
;
49 /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
50 static int shutdown_openocd
= 0;
51 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 int add_connection(service_t
*service
, command_context_t
*cmd_ctx
)
55 unsigned int address_size
;
60 c
= malloc(sizeof(connection_t
));
62 memset(&c
->sin
, 0, sizeof(c
->sin
));
63 c
->cmd_ctx
= copy_command_context(cmd_ctx
);
69 address_size
= sizeof(c
->sin
);
71 c
->fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
73 /* This increases performance dramatically for e.g. GDB load which
74 * does not have a sliding window protocol. */
75 retval
=setsockopt(c
->fd
, /* socket affected */
76 IPPROTO_TCP
, /* set option at TCP level */
77 TCP_NODELAY
, /* name of option */
78 (char *)&flag
, /* the cast is historical cruft */
79 sizeof(int)); /* length of option value */
81 LOG_INFO("accepting '%s' connection from %i", service
->name
, c
->sin
.sin_port
);
82 if ((retval
= service
->new_connection(c
)) == ERROR_OK
)
88 LOG_ERROR("attempted '%s' connection rejected", service
->name
);
93 /* add to the end of linked list */
94 for (p
= &service
->connections
; *p
; p
= &(*p
)->next
);
97 service
->max_connections
--;
102 int remove_connection(service_t
*service
, connection_t
*connection
)
104 connection_t
**p
= &service
->connections
;
107 /* find connection */
110 if (c
->fd
== connection
->fd
)
112 service
->connection_closed(c
);
114 command_done(c
->cmd_ctx
);
116 /* delete connection */
120 service
->max_connections
++;
124 /* redirect p to next list pointer */
131 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
)
134 int so_reuseaddr_option
= 1;
136 c
= malloc(sizeof(service_t
));
138 c
->name
= strdup(name
);
141 c
->max_connections
= max_connections
;
143 c
->connections
= NULL
;
144 c
->new_connection
= new_connection_handler
;
145 c
->input
= input_handler
;
146 c
->connection_closed
= connection_closed_handler
;
150 if ((c
->fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
152 LOG_ERROR("error creating socket: %s", strerror(errno
));
156 setsockopt(c
->fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
158 socket_nonblock(c
->fd
);
160 memset(&c
->sin
, 0, sizeof(c
->sin
));
161 c
->sin
.sin_family
= AF_INET
;
162 c
->sin
.sin_addr
.s_addr
= INADDR_ANY
;
163 c
->sin
.sin_port
= htons(port
);
165 if (bind(c
->fd
, (struct sockaddr
*)&c
->sin
, sizeof(c
->sin
)) == -1)
167 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
173 setsockopt(c
->fd
, IPPROTO_TCP
, TCP_MAXSEG
, &segsize
, sizeof(int));
175 int window_size
= 128 * 1024;
177 /* These setsockopt()s must happen before the listen() */
179 setsockopt(c
->fd
, SOL_SOCKET
, SO_SNDBUF
,
180 (char *)&window_size
, sizeof(window_size
));
181 setsockopt(c
->fd
, SOL_SOCKET
, SO_RCVBUF
,
182 (char *)&window_size
, sizeof(window_size
));
184 if (listen(c
->fd
, 1) == -1)
186 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
190 /* add to the end of linked list */
191 for (p
= &services
; *p
; p
= &(*p
)->next
);
197 int remove_service(unsigned short port
)
199 service_t
**p
= &services
;
218 /* redirect p to next list pointer */
225 int remove_services(void)
227 service_t
*c
= services
;
232 service_t
*next
= c
->next
;
243 /* remember the last service for unlinking */
252 extern void openocd_sleep_prelude(void);
253 extern void openocd_sleep_postlude(void);
255 int server_loop(command_context_t
*command_context
)
259 /* used in select() */
264 /* used in accept() */
268 if (signal(SIGPIPE
, SIG_IGN
) == SIG_ERR
)
269 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
272 /* do regular tasks after at most 10ms */
276 while(!shutdown_openocd
)
278 /* monitor sockets for acitvity */
282 /* add service and connection fds to read_fds */
283 for (service
= services
; service
; service
= service
->next
)
285 if (service
->fd
!= -1)
287 /* listen for new connections */
288 FD_SET(service
->fd
, &read_fds
);
290 if (service
->fd
> fd_max
)
291 fd_max
= service
->fd
;
294 if (service
->connections
)
298 for (c
= service
->connections
; c
; c
= c
->next
)
300 /* check for activity on the connection */
301 FD_SET(c
->fd
, &read_fds
);
309 #if BUILD_ECOSBOARD == 0
310 /* add STDIN to read_fds */
311 FD_SET(fileno(stdin
), &read_fds
);
315 openocd_sleep_prelude();
317 // Only while we're sleeping we'll let others run
318 retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
319 openocd_sleep_postlude();
325 errno
= WSAGetLastError();
327 if (errno
== WSAEINTR
)
331 LOG_ERROR("error during select: %s", strerror(errno
));
342 LOG_ERROR("error during select: %s", strerror(errno
));
348 target_call_timer_callbacks();
349 process_jim_events ();
353 /* do regular tasks after at most 100ms */
356 FD_ZERO(&read_fds
); /* eCos leaves read_fds unchanged in this case! */
359 for (service
= services
; service
; service
= service
->next
)
361 /* handle new connections on listeners */
362 if ((service
->fd
!= -1)
363 && (FD_ISSET(service
->fd
, &read_fds
)))
365 if (service
->max_connections
> 0)
367 add_connection(service
, command_context
);
371 struct sockaddr_in sin
;
372 unsigned int address_size
= sizeof(sin
);
374 tmp_fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
375 close_socket(tmp_fd
);
376 LOG_INFO("rejected '%s' connection, no more connections allowed", service
->name
);
380 /* handle activity on connections */
381 if (service
->connections
)
385 for (c
= service
->connections
; c
;)
387 if ((FD_ISSET(c
->fd
, &read_fds
)) || c
->input_pending
)
389 if (service
->input(c
) != ERROR_OK
)
391 connection_t
*next
= c
->next
;
392 remove_connection(service
, c
);
393 LOG_INFO("dropped '%s' connection", service
->name
);
404 #if BUILD_ECOSBOARD == 0
405 if (FD_ISSET(fileno(stdin
), &read_fds
))
407 if (getc(stdin
) == 'x')
409 shutdown_openocd
= 1;
415 while (PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
))
417 if (msg
.message
== WM_QUIT
)
418 shutdown_openocd
= 1;
427 BOOL WINAPI
ControlHandler(DWORD dwCtrlType
)
429 shutdown_openocd
= 1;
433 void sig_handler(int sig
) {
434 shutdown_openocd
= 1;
438 int server_init(void)
441 WORD wVersionRequested
;
444 wVersionRequested
= MAKEWORD( 2, 2 );
446 if (WSAStartup(wVersionRequested
, &wsaData
) != 0)
448 LOG_ERROR("Failed to Open Winsock");
452 SetConsoleCtrlHandler( ControlHandler
, TRUE
);
454 signal(SIGINT
, sig_handler
);
455 signal(SIGTERM
, sig_handler
);
456 signal(SIGBREAK
, sig_handler
);
457 signal(SIGABRT
, sig_handler
);
464 int server_quit(void)
470 SetConsoleCtrlHandler( ControlHandler
, FALSE
);
476 int server_register_commands(command_context_t
*context
)
478 register_command(context
, NULL
, "shutdown", handle_shutdown_command
,
479 COMMAND_ANY
, "shut the server down");
484 /* tell the server we want to shut down */
485 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
487 shutdown_openocd
= 1;
489 return ERROR_COMMAND_CLOSE_CONNECTION
;
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)