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
;
59 c
= malloc(sizeof(connection_t
));
61 memset(&c
->sin
, 0, sizeof(c
->sin
));
62 c
->cmd_ctx
= copy_command_context(cmd_ctx
);
68 address_size
= sizeof(c
->sin
);
71 setsockopt(service
->fd
, IPPROTO_TCP
, TCP_MAXSEG
, &segsize
, sizeof(int));
72 int window_size
= 128 * 1024;
74 /* These setsockopt()s must happen before the accept() */
76 setsockopt(service
->fd
, SOL_SOCKET
, SO_SNDBUF
,
77 (char *) &window_size
, sizeof(window_size
));
79 setsockopt(service
->fd
, SOL_SOCKET
, SO_RCVBUF
,
80 (char *) &window_size
, sizeof(window_size
));
83 c
->fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
85 // This increases performance dramatically for e.g. GDB load which
86 // does not have a sliding window protocol.
87 retval
=setsockopt(c
->fd
, /* socket affected */
88 IPPROTO_TCP
, /* set option at TCP level */
89 TCP_NODELAY
, /* name of option */
90 (char *) &flag
, /* the cast is historical
92 sizeof(int)); /* length of option value */
93 setsockopt(c
->fd
, IPPROTO_TCP
, TCP_MAXSEG
, &segsize
, sizeof(int));
97 LOG_INFO("accepting '%s' connection from %i", service
->name
, c
->sin
.sin_port
);
98 if ((retval
= service
->new_connection(c
)) == ERROR_OK
)
104 LOG_ERROR("attempted '%s' connection rejected", service
->name
);
109 /* add to the end of linked list */
110 for (p
= &service
->connections
; *p
; p
= &(*p
)->next
);
113 service
->max_connections
--;
118 int remove_connection(service_t
*service
, connection_t
*connection
)
120 connection_t
**p
= &service
->connections
;
123 /* find connection */
126 if (c
->fd
== connection
->fd
)
128 service
->connection_closed(c
);
130 command_done(c
->cmd_ctx
);
132 /* delete connection */
136 service
->max_connections
++;
140 /* redirect p to next list pointer */
147 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
)
150 int so_reuseaddr_option
= 1;
152 c
= malloc(sizeof(service_t
));
154 c
->name
= strdup(name
);
157 c
->max_connections
= max_connections
;
159 c
->connections
= NULL
;
160 c
->new_connection
= new_connection_handler
;
161 c
->input
= input_handler
;
162 c
->connection_closed
= connection_closed_handler
;
166 if ((c
->fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
168 LOG_ERROR("error creating socket: %s", strerror(errno
));
172 setsockopt(c
->fd
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&so_reuseaddr_option
, sizeof(int));
174 socket_nonblock(c
->fd
);
176 memset(&c
->sin
, 0, sizeof(c
->sin
));
177 c
->sin
.sin_family
= AF_INET
;
178 c
->sin
.sin_addr
.s_addr
= INADDR_ANY
;
179 c
->sin
.sin_port
= htons(port
);
181 if (bind(c
->fd
, (struct sockaddr
*)&c
->sin
, sizeof(c
->sin
)) == -1)
183 LOG_ERROR("couldn't bind to socket: %s", strerror(errno
));
187 if (listen(c
->fd
, 1) == -1)
189 LOG_ERROR("couldn't listen on socket: %s", strerror(errno
));
193 /* add to the end of linked list */
194 for (p
= &services
; *p
; p
= &(*p
)->next
);
200 int remove_service(unsigned short port
)
202 service_t
**p
= &services
;
221 /* redirect p to next list pointer */
228 int remove_services()
230 service_t
*c
= services
;
235 service_t
*next
= c
->next
;
246 /* remember the last service for unlinking */
255 extern void lockBigLock();
256 extern void unlockBigLock();
258 int server_loop(command_context_t
*command_context
)
262 /* used in select() */
267 /* used in accept() */
271 if (signal(SIGPIPE
, SIG_IGN
) == SIG_ERR
)
272 LOG_ERROR("couldn't set SIGPIPE to SIG_IGN");
275 // This function is reentrant(workaround for configuration problems)
276 static int lockCount
=0;
282 /* do regular tasks after at most 10ms */
286 while(!shutdown_openocd
)
288 /* monitor sockets for acitvity */
292 /* add service and connection fds to read_fds */
293 for (service
= services
; service
; service
= service
->next
)
295 if (service
->fd
!= -1)
297 /* listen for new connections */
298 FD_SET(service
->fd
, &read_fds
);
300 if (service
->fd
> fd_max
)
301 fd_max
= service
->fd
;
304 if (service
->connections
)
308 for (c
= service
->connections
; c
; c
= c
->next
)
310 /* check for activity on the connection */
311 FD_SET(c
->fd
, &read_fds
);
319 #ifndef BUILD_ECOSBOARD
320 /* add STDIN to read_fds */
321 FD_SET(fileno(stdin
), &read_fds
);
325 // Only while we're sleeping we'll let others run
327 retval
= select(fd_max
+ 1, &read_fds
, NULL
, NULL
, &tv
);
334 errno
= WSAGetLastError();
336 if (errno
== WSAEINTR
)
340 LOG_ERROR("error during select: %s", strerror(errno
));
351 LOG_ERROR("error during select: %s", strerror(errno
));
357 target_call_timer_callbacks();
361 /* do regular tasks after at most 100ms */
364 FD_ZERO(&read_fds
); /* eCos leaves read_fds unchanged in this case! */
367 for (service
= services
; service
; service
= service
->next
)
369 /* handle new connections on listeners */
370 if ((service
->fd
!= -1)
371 && (FD_ISSET(service
->fd
, &read_fds
)))
373 if (service
->max_connections
> 0)
375 add_connection(service
, command_context
);
379 struct sockaddr_in sin
;
380 unsigned int address_size
= sizeof(sin
);
382 tmp_fd
= accept(service
->fd
, (struct sockaddr
*)&service
->sin
, &address_size
);
383 close_socket(tmp_fd
);
384 LOG_INFO("rejected '%s' connection, no more connections allowed", service
->name
);
388 /* handle activity on connections */
389 if (service
->connections
)
393 for (c
= service
->connections
; c
;)
395 if ((FD_ISSET(c
->fd
, &read_fds
)) || c
->input_pending
)
397 if (service
->input(c
) != ERROR_OK
)
399 connection_t
*next
= c
->next
;
400 remove_connection(service
, c
);
401 LOG_INFO("dropped '%s' connection", service
->name
);
412 #ifndef BUILD_ECOSBOARD
413 if (FD_ISSET(fileno(stdin
), &read_fds
))
415 if (getc(stdin
) == 'x')
417 shutdown_openocd
= 1;
423 while (PeekMessage(&msg
,NULL
,0,0,PM_REMOVE
))
425 if (msg
.message
== WM_QUIT
)
426 shutdown_openocd
= 1;
439 BOOL WINAPI
ControlHandler(DWORD dwCtrlType
)
441 shutdown_openocd
= 1;
445 void sig_handler(int sig
) {
446 shutdown_openocd
= 1;
453 WORD wVersionRequested
;
456 wVersionRequested
= MAKEWORD( 2, 2 );
458 if (WSAStartup(wVersionRequested
, &wsaData
) != 0)
460 LOG_ERROR("Failed to Open Winsock");
464 SetConsoleCtrlHandler( ControlHandler
, TRUE
);
466 signal(SIGINT
, sig_handler
);
467 signal(SIGTERM
, sig_handler
);
468 signal(SIGBREAK
, sig_handler
);
469 signal(SIGABRT
, sig_handler
);
482 SetConsoleCtrlHandler( ControlHandler
, FALSE
);
488 int server_register_commands(command_context_t
*context
)
490 register_command(context
, NULL
, "shutdown", handle_shutdown_command
,
491 COMMAND_ANY
, "shut the server down");
496 /* tell the server we want to shut down */
497 int handle_shutdown_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
499 shutdown_openocd
= 1;
501 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)