1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
29 #include "telnet_server.h"
37 #include <sys/types.h>
41 #include <netinet/tcp.h>
44 service_t
*services
= NULL
;
46 /* shutdown_openocd == 1: exit the main event loop, and quit the debugger */
47 static int shutdown_openocd
= 0;
48 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 int add_connection(service_t
*service
, command_context_t
*cmd_ctx
)
52 unsigned int address_size
;
57 c
= malloc(sizeof(connection_t
));
59 memset(&c
->sin
, 0, sizeof(c
->sin
));
60 c
->cmd_ctx
= copy_command_context(cmd_ctx
);
66 address_size
= sizeof(c
->sin
);
68 c
->fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
70 /* This increases performance dramatically for e.g. GDB load which
71 * does not have a sliding window protocol. */
72 retval
=setsockopt(c
->fd
, /* socket affected */
73 IPPROTO_TCP
, /* set option at TCP level */
74 TCP_NODELAY
, /* name of option */
75 (char *)&flag
, /* the cast is historical cruft */
76 sizeof(int)); /* length of option value */
78 LOG_INFO("accepting '%s' connection from %i", service
->name
, c
->sin
.sin_port
);
79 if ((retval
= service
->new_connection(c
)) == ERROR_OK
)
85 LOG_ERROR("attempted '%s' connection rejected", service
->name
);
90 /* add to the end of linked list */
91 for (p
= &service
->connections
; *p
; p
= &(*p
)->next
);
94 service
->max_connections
--;
99 int remove_connection(service_t
*service
, connection_t
*connection
)
101 connection_t
**p
= &service
->connections
;
104 /* find connection */
107 if (c
->fd
== connection
->fd
)
109 service
->connection_closed(c
);
111 command_done(c
->cmd_ctx
);
113 /* delete connection */
117 service
->max_connections
++;
121 /* redirect p to next list pointer */
128 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
)
131 int so_reuseaddr_option
= 1;
133 c
= malloc(sizeof(service_t
));
135 c
->name
= strdup(name
);
138 c
->max_connections
= max_connections
;
140 c
->connections
= NULL
;
141 c
->new_connection
= new_connection_handler
;
142 c
->input
= input_handler
;
143 c
->connection_closed
= connection_closed_handler
;
147 if ((c
->fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
149 LOG_ERROR("error creating socket: %s", strerror(errno
));
153 setsockopt(c
->fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
155 socket_nonblock(c
->fd
);
157 memset(&c
->sin
, 0, sizeof(c
->sin
));
158 c
->sin
.sin_family
= AF_INET
;
159 c
->sin
.sin_addr
.s_addr
= INADDR_ANY
;
160 c
->sin
.sin_port
= htons(port
);
162 if (bind(c
->fd
, (struct sockaddr
*)&c
->sin
, sizeof(c
->sin
)) == -1)
164 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
170 setsockopt(c
->fd
, IPPROTO_TCP
, TCP_MAXSEG
, &segsize
, sizeof(int));
172 int window_size
= 128 * 1024;
174 /* These setsockopt()s must happen before the listen() */
176 setsockopt(c
->fd
, SOL_SOCKET
, SO_SNDBUF
,
177 (char *)&window_size
, sizeof(window_size
));
178 setsockopt(c
->fd
, SOL_SOCKET
, SO_RCVBUF
,
179 (char *)&window_size
, sizeof(window_size
));
181 if (listen(c
->fd
, 1) == -1)
183 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
187 /* add to the end of linked list */
188 for (p
= &services
; *p
; p
= &(*p
)->next
);
194 int remove_service(unsigned short port
)
196 service_t
**p
= &services
;
215 /* redirect p to next list pointer */
222 int remove_services()
224 service_t
*c
= services
;
229 service_t
*next
= c
->next
;
240 /* remember the last service for unlinking */
249 extern void lockBigLock();
250 extern void unlockBigLock();
252 int server_loop(command_context_t
*command_context
)
256 /* used in select() */
261 /* used in accept() */
265 if (signal(SIGPIPE
, SIG_IGN
) == SIG_ERR
)
266 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
269 // This function is reentrant(workaround for configuration problems)
270 static int lockCount
=0;
276 /* do regular tasks after at most 10ms */
280 while(!shutdown_openocd
)
282 /* monitor sockets for acitvity */
286 /* add service and connection fds to read_fds */
287 for (service
= services
; service
; service
= service
->next
)
289 if (service
->fd
!= -1)
291 /* listen for new connections */
292 FD_SET(service
->fd
, &read_fds
);
294 if (service
->fd
> fd_max
)
295 fd_max
= service
->fd
;
298 if (service
->connections
)
302 for (c
= service
->connections
; c
; c
= c
->next
)
304 /* check for activity on the connection */
305 FD_SET(c
->fd
, &read_fds
);
313 #ifndef BUILD_ECOSBOARD
314 /* add STDIN to read_fds */
315 FD_SET(fileno(stdin
), &read_fds
);
319 // Only while we're sleeping we'll let others run
321 retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
328 errno
= WSAGetLastError();
330 if (errno
== WSAEINTR
)
334 LOG_ERROR("error during select: %s", strerror(errno
));
345 LOG_ERROR("error during select: %s", strerror(errno
));
351 target_call_timer_callbacks();
355 /* do regular tasks after at most 100ms */
358 FD_ZERO(&read_fds
); /* eCos leaves read_fds unchanged in this case! */
361 for (service
= services
; service
; service
= service
->next
)
363 /* handle new connections on listeners */
364 if ((service
->fd
!= -1)
365 && (FD_ISSET(service
->fd
, &read_fds
)))
367 if (service
->max_connections
> 0)
369 add_connection(service
, command_context
);
373 struct sockaddr_in sin
;
374 unsigned int address_size
= sizeof(sin
);
376 tmp_fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
377 close_socket(tmp_fd
);
378 LOG_INFO("rejected '%s' connection, no more connections allowed", service
->name
);
382 /* handle activity on connections */
383 if (service
->connections
)
387 for (c
= service
->connections
; c
;)
389 if ((FD_ISSET(c
->fd
, &read_fds
)) || c
->input_pending
)
391 if (service
->input(c
) != ERROR_OK
)
393 connection_t
*next
= c
->next
;
394 remove_connection(service
, c
);
395 LOG_INFO("dropped '%s' connection", service
->name
);
406 #ifndef BUILD_ECOSBOARD
407 if (FD_ISSET(fileno(stdin
), &read_fds
))
409 if (getc(stdin
) == 'x')
411 shutdown_openocd
= 1;
417 while (PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
))
419 if (msg
.message
== WM_QUIT
)
420 shutdown_openocd
= 1;
433 BOOL WINAPI
ControlHandler(DWORD dwCtrlType
)
435 shutdown_openocd
= 1;
439 void sig_handler(int sig
) {
440 shutdown_openocd
= 1;
447 WORD wVersionRequested
;
450 wVersionRequested
= MAKEWORD( 2, 2 );
452 if (WSAStartup(wVersionRequested
, &wsaData
) != 0)
454 LOG_ERROR("Failed to Open Winsock");
458 SetConsoleCtrlHandler( ControlHandler
, TRUE
);
460 signal(SIGINT
, sig_handler
);
461 signal(SIGTERM
, sig_handler
);
462 signal(SIGBREAK
, sig_handler
);
463 signal(SIGABRT
, sig_handler
);
475 SetConsoleCtrlHandler( ControlHandler
, FALSE
);
481 int server_register_commands(command_context_t
*context
)
483 register_command(context
, NULL
, "shutdown", handle_shutdown_command
,
484 COMMAND_ANY
, "shut the server down");
489 /* tell the server we want to shut down */
490 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
492 shutdown_openocd
= 1;
494 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)