chiark / gitweb /
1b23483881549caa3de4ce14882a8360e5e1bdfb
[elogind.git] / socket.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <unistd.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <sys/poll.h>
9 #include <signal.h>
10
11 #include "unit.h"
12 #include "socket.h"
13 #include "log.h"
14
15 static const UnitActiveState state_table[_SOCKET_STATE_MAX] = {
16         [SOCKET_DEAD] = UNIT_INACTIVE,
17         [SOCKET_START_PRE] = UNIT_ACTIVATING,
18         [SOCKET_START_POST] = UNIT_ACTIVATING,
19         [SOCKET_LISTENING] = UNIT_ACTIVE,
20         [SOCKET_RUNNING] = UNIT_ACTIVE,
21         [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
22         [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
23         [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
24         [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
25         [SOCKET_STOP_POST_SIGTERM] = UNIT_DEACTIVATING,
26         [SOCKET_STOP_POST_SIGKILL] = UNIT_DEACTIVATING,
27         [SOCKET_MAINTAINANCE] = UNIT_INACTIVE,
28 };
29
30 static void socket_done(Unit *u) {
31         Socket *s = SOCKET(u);
32         SocketPort *p;
33
34         assert(s);
35
36         while ((p = s->ports)) {
37                 LIST_REMOVE(SocketPort, port, s->ports, p);
38
39                 if (p->fd >= 0)
40                         close_nointr(p->fd);
41                 free(p->path);
42                 free(p);
43         }
44
45         exec_context_done(&s->exec_context);
46         exec_command_free_array(s->exec_command, _SOCKET_EXEC_MAX);
47         s->control_command = NULL;
48
49         if (s->control_pid > 0) {
50                 unit_unwatch_pid(u, s->control_pid);
51                 s->control_pid = 0;
52         }
53
54         s->service = NULL;
55
56         unit_unwatch_timer(u, &s->timer_id);
57 }
58
59 static int socket_init(Unit *u) {
60         Socket *s = SOCKET(u);
61         char *t;
62         int r;
63
64         /* First, reset everything to the defaults, in case this is a
65          * reload */
66
67         s->state = 0;
68         s->timer_id = -1;
69         s->bind_ipv6_only = false;
70         s->backlog = SOMAXCONN;
71         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
72         exec_context_init(&s->exec_context);
73
74         if ((r = unit_load_fragment_and_dropin(u)) < 0)
75                 goto fail;
76
77         if (!(t = unit_name_change_suffix(unit_id(u), ".service"))) {
78                 r = -ENOMEM;
79                 goto fail;
80         }
81
82         r = manager_load_unit(u->meta.manager, t, (Unit**) &s->service);
83         free(t);
84
85         if (r < 0)
86                 goto fail;
87
88         if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0)
89                 goto fail;
90
91         return 0;
92
93 fail:
94         socket_done(u);
95         return r;
96 }
97
98 static const char* listen_lookup(int type) {
99
100         if (type == SOCK_STREAM)
101                 return "ListenStream";
102         else if (type == SOCK_DGRAM)
103                 return "ListenDatagram";
104         else if (type == SOCK_SEQPACKET)
105                 return "ListenSequentialPacket";
106
107         assert_not_reached("Unknown socket type");
108         return NULL;
109 }
110
111 static void socket_dump(Unit *u, FILE *f, const char *prefix) {
112
113         static const char* const state_table[_SOCKET_STATE_MAX] = {
114                 [SOCKET_DEAD] = "dead",
115                 [SOCKET_START_PRE] = "start-pre",
116                 [SOCKET_START_POST] = "start-post",
117                 [SOCKET_LISTENING] = "listening",
118                 [SOCKET_RUNNING] = "running",
119                 [SOCKET_STOP_PRE] = "stop-pre",
120                 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
121                 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
122                 [SOCKET_STOP_POST] = "stop-post",
123                 [SOCKET_STOP_POST_SIGTERM] = "stop-post-sigterm",
124                 [SOCKET_STOP_POST_SIGKILL] = "stop-post-sigkill",
125                 [SOCKET_MAINTAINANCE] = "maintainance"
126         };
127
128         static const char* const command_table[_SOCKET_EXEC_MAX] = {
129                 [SOCKET_EXEC_START_PRE] = "StartPre",
130                 [SOCKET_EXEC_START_POST] = "StartPost",
131                 [SOCKET_EXEC_STOP_PRE] = "StopPre",
132                 [SOCKET_EXEC_STOP_POST] = "StopPost"
133         };
134
135         SocketExecCommand c;
136         Socket *s = SOCKET(u);
137         SocketPort *p;
138         char *prefix2;
139
140         assert(s);
141
142         prefix2 = strappend(prefix, "\t");
143         if (!prefix2)
144                 prefix2 = "";
145
146         fprintf(f,
147                 "%sSocket State: %s\n"
148                 "%sBindIPv6Only: %s\n"
149                 "%sBacklog: %u\n",
150                 prefix, state_table[s->state],
151                 prefix, yes_no(s->bind_ipv6_only),
152                 prefix, s->backlog);
153
154         LIST_FOREACH(port, p, s->ports) {
155
156                 if (p->type == SOCKET_SOCKET) {
157                         const char *t;
158                         int r;
159                         char *k;
160
161                         if ((r = socket_address_print(&p->address, &k)) < 0)
162                                 t = strerror(-r);
163                         else
164                                 t = k;
165
166                         fprintf(f, "%s%s: %s\n", prefix, listen_lookup(p->address.type), k);
167                         free(k);
168                 } else
169                         fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
170         }
171
172         exec_context_dump(&s->exec_context, f, prefix);
173
174         for (c = 0; c < _SOCKET_EXEC_MAX; c++) {
175                 if (!s->exec_command[c])
176                         continue;
177
178                 fprintf(f, "%s→ %s:\n",
179                         prefix, command_table[c]);
180
181                 exec_command_dump_list(s->exec_command[c], f, prefix2);
182         }
183
184         free(prefix2);
185 }
186
187 static void socket_close_fds(Socket *s) {
188         SocketPort *p;
189
190         assert(s);
191
192         LIST_FOREACH(port, p, s->ports) {
193                 if (p->fd < 0)
194                         continue;
195
196                 unit_unwatch_fd(UNIT(s), p->fd);
197                 assert_se(close_nointr(p->fd) >= 0);
198
199                 p->fd = -1;
200         }
201 }
202
203 static int socket_open_fds(Socket *s) {
204         SocketPort *p;
205         int r;
206
207         assert(s);
208
209         LIST_FOREACH(port, p, s->ports) {
210
211                 if (p->fd >= 0)
212                         continue;
213
214                 if (p->type == SOCKET_SOCKET) {
215
216                         if ((r = socket_address_listen(&p->address, s->backlog, s->bind_ipv6_only, &p->fd)) < 0)
217                                 goto rollback;
218
219                 } else {
220                         struct stat st;
221                         assert(p->type == SOCKET_FIFO);
222
223                         if (mkfifo(p->path, 0666 & ~s->exec_context.umask) < 0 && errno != EEXIST) {
224                                 r = -errno;
225                                 goto rollback;
226                         }
227
228                         if ((p->fd = open(p->path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
229                                 r = -errno;
230                                 goto rollback;
231                         }
232
233                         if (fstat(p->fd, &st) < 0) {
234                                 r = -errno;
235                                 goto rollback;
236                         }
237
238                         /* FIXME verify user, access mode */
239
240                         if (!S_ISFIFO(st.st_mode)) {
241                                 r = -EEXIST;
242                                 goto rollback;
243                         }
244                 }
245         }
246
247         return 0;
248
249 rollback:
250         socket_close_fds(s);
251         return r;
252 }
253
254 static void socket_unwatch_fds(Socket *s) {
255         SocketPort *p;
256
257         assert(s);
258
259         LIST_FOREACH(port, p, s->ports) {
260                 if (p->fd < 0)
261                         continue;
262
263                 unit_unwatch_fd(UNIT(s), p->fd);
264         }
265 }
266
267 static int socket_watch_fds(Socket *s) {
268         SocketPort *p;
269         int r;
270
271         assert(s);
272
273         LIST_FOREACH(port, p, s->ports) {
274                 if (p->fd < 0)
275                         continue;
276
277                 if ((r = unit_watch_fd(UNIT(s), p->fd, POLLIN)) < 0)
278                         goto fail;
279         }
280
281         return 0;
282
283 fail:
284         socket_unwatch_fds(s);
285         return r;
286 }
287
288 static void socket_set_state(Socket *s, SocketState state) {
289         SocketState old_state;
290         assert(s);
291
292         old_state = s->state;
293         s->state = state;
294
295         if (state != SOCKET_START_PRE &&
296             state != SOCKET_START_POST &&
297             state != SOCKET_STOP_PRE &&
298             state != SOCKET_STOP_PRE_SIGTERM &&
299             state != SOCKET_STOP_PRE_SIGKILL &&
300             state != SOCKET_STOP_POST &&
301             state != SOCKET_STOP_POST_SIGTERM &&
302             state != SOCKET_STOP_POST_SIGKILL)
303                 unit_unwatch_timer(UNIT(s), &s->timer_id);
304
305         if (state != SOCKET_START_PRE &&
306             state != SOCKET_START_POST &&
307             state != SOCKET_STOP_PRE &&
308             state != SOCKET_STOP_PRE_SIGTERM &&
309             state != SOCKET_STOP_PRE_SIGKILL &&
310             state != SOCKET_STOP_POST &&
311             state != SOCKET_STOP_POST_SIGTERM &&
312             state != SOCKET_STOP_POST_SIGKILL)
313                 if (s->control_pid >= 0) {
314                         unit_unwatch_pid(UNIT(s), s->control_pid);
315                         s->control_pid = 0;
316                 }
317
318         if (state != SOCKET_START_PRE &&
319             state != SOCKET_START_POST &&
320             state != SOCKET_STOP_PRE &&
321             state != SOCKET_STOP_POST)
322                 s->control_command = NULL;
323
324         if (state != SOCKET_START_POST &&
325             state != SOCKET_LISTENING &&
326             state != SOCKET_RUNNING &&
327             state != SOCKET_STOP_PRE &&
328             state != SOCKET_STOP_PRE_SIGTERM &&
329             state != SOCKET_STOP_PRE_SIGKILL)
330                 socket_close_fds(s);
331
332         if (state != SOCKET_LISTENING)
333                 socket_unwatch_fds(s);
334
335         unit_notify(UNIT(s), state_table[old_state], state_table[s->state]);
336 }
337
338 static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
339         pid_t pid;
340         int r;
341
342         assert(s);
343         assert(c);
344         assert(_pid);
345
346         if (timeout) {
347                 if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_id)) < 0)
348                         goto fail;
349         } else
350                 unit_unwatch_timer(UNIT(s), &s->timer_id);
351
352         if ((r = exec_spawn(c, &s->exec_context, NULL, 0, &pid)) < 0)
353                 goto fail;
354
355         if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
356                 /* FIXME: we need to do something here */
357                 goto fail;
358
359         *_pid = pid;
360
361         return 0;
362
363 fail:
364         if (timeout)
365                 unit_unwatch_timer(UNIT(s), &s->timer_id);
366
367         return r;
368 }
369
370 static void socket_enter_dead(Socket *s, bool success) {
371         assert(s);
372
373         if (!success)
374                 s->failure = true;
375
376         socket_set_state(s, s->failure ? SOCKET_MAINTAINANCE : SOCKET_DEAD);
377 }
378
379 static void socket_enter_stop_post(Socket *s, bool success) {
380         int r;
381         assert(s);
382
383         if (!success)
384                 s->failure = true;
385
386         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
387
388                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
389                         goto fail;
390
391                 socket_set_state(s, SOCKET_STOP_POST);
392         } else
393                 socket_enter_dead(s, true);
394
395         return;
396
397 fail:
398         log_warning("%s failed to run stop-post executable: %s", unit_id(UNIT(s)), strerror(-r));
399         socket_enter_dead(s, false);
400 }
401
402 static void socket_enter_signal(Socket *s, SocketState state, bool success) {
403         int r;
404
405         assert(s);
406
407         if (!success)
408                 s->failure = true;
409
410         if (s->control_pid > 0) {
411                 int sig;
412
413                 sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_POST_SIGTERM) ? SIGTERM : SIGKILL;
414
415                 if (kill(s->control_pid, sig) < 0 && errno != ESRCH) {
416                         r = -errno;
417                         goto fail;
418                 }
419
420                 socket_set_state(s, state);
421         } else
422                 socket_enter_dead(s, true);
423
424         return;
425
426 fail:
427         log_warning("%s failed to kill processes: %s", unit_id(UNIT(s)), strerror(-r));
428
429         if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
430                 socket_enter_stop_post(s, false);
431         else
432                 socket_enter_dead(s, false);
433 }
434
435 static void socket_enter_stop_pre(Socket *s, bool success) {
436         int r;
437         assert(s);
438
439         if (!success)
440                 s->failure = true;
441
442         if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
443
444                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
445                         goto fail;
446
447                 socket_set_state(s, SOCKET_STOP_PRE);
448         } else
449                 socket_enter_stop_post(s, true);
450
451         return;
452
453 fail:
454         log_warning("%s failed to run stop-pre executable: %s", unit_id(UNIT(s)), strerror(-r));
455         socket_enter_stop_post(s, false);
456 }
457
458 static void socket_enter_start_post(Socket *s) {
459         int r;
460         assert(s);
461
462         if ((r = socket_open_fds(s)) < 0 ||
463             (r = socket_watch_fds(s)) < 0) {
464                 log_warning("%s failed to listen on sockets: %s", unit_id(UNIT(s)), strerror(-r));
465                 goto fail;
466         }
467
468         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
469
470                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0) {
471                         log_warning("%s failed to run start-post executable: %s", unit_id(UNIT(s)), strerror(-r));
472                         goto fail;
473                 }
474
475                 socket_set_state(s, SOCKET_START_POST);
476         } else
477                 socket_set_state(s, SOCKET_LISTENING);
478
479         return;
480
481 fail:
482         socket_enter_stop_pre(s, false);
483 }
484
485 static void socket_enter_start_pre(Socket *s) {
486         int r;
487         assert(s);
488
489         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
490
491                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
492                         goto fail;
493
494                 socket_set_state(s, SOCKET_START_PRE);
495         } else
496                 socket_enter_start_post(s);
497
498         return;
499
500 fail:
501         log_warning("%s failed to run start-pre exectuable: %s", unit_id(UNIT(s)), strerror(-r));
502         socket_enter_dead(s, false);
503 }
504
505 static void socket_enter_running(Socket *s) {
506         int r;
507
508         assert(s);
509
510         if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, NULL)) < 0)
511                 goto fail;
512
513         socket_set_state(s, SOCKET_RUNNING);
514         return;
515
516 fail:
517         log_warning("%s failed to queue socket startup job: %s", unit_id(UNIT(s)), strerror(-r));
518         socket_enter_dead(s, false);
519 }
520
521 static void socket_run_next(Socket *s, bool success) {
522         int r;
523
524         assert(s);
525         assert(s->control_command);
526         assert(s->control_command->command_next);
527
528         if (!success)
529                 s->failure = true;
530
531         s->control_command = s->control_command->command_next;
532
533         if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0)
534                 goto fail;
535
536         return;
537
538 fail:
539         if (s->state == SOCKET_STOP_PRE)
540                 socket_enter_stop_post(s, false);
541         else if (s->state == SOCKET_STOP_POST)
542                 socket_enter_dead(s, false);
543         else
544                 socket_enter_stop_pre(s, false);
545 }
546
547 static int socket_start(Unit *u) {
548         Socket *s = SOCKET(u);
549
550         assert(s);
551
552         /* We cannot fulfill this request right now, try again later
553          * please! */
554         if (s->state == SOCKET_STOP_PRE ||
555             s->state == SOCKET_STOP_PRE_SIGKILL ||
556             s->state == SOCKET_STOP_PRE_SIGTERM ||
557             s->state == SOCKET_STOP_POST ||
558             s->state == SOCKET_STOP_POST_SIGTERM ||
559             s->state == SOCKET_STOP_POST_SIGKILL)
560                 return -EAGAIN;
561
562         if (s->state == SOCKET_START_PRE ||
563             s->state == SOCKET_START_POST)
564                 return 0;
565
566         /* Cannot run this without the service being around */
567         if (s->service->meta.load_state != UNIT_LOADED)
568                 return -ENOENT;
569
570         assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
571
572         s->failure = false;
573         socket_enter_start_pre(s);
574         return 0;
575 }
576
577 static int socket_stop(Unit *u) {
578         Socket *s = SOCKET(u);
579
580         assert(s);
581
582         /* We cannot fulfill this request right now, try again later
583          * please! */
584         if (s->state == SOCKET_START_PRE ||
585             s->state == SOCKET_START_POST)
586                 return -EAGAIN;
587
588         assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
589
590         socket_enter_stop_pre(s, true);
591         return 0;
592 }
593
594 static UnitActiveState socket_active_state(Unit *u) {
595         assert(u);
596
597         return state_table[SOCKET(u)->state];
598 }
599
600 static void socket_fd_event(Unit *u, int fd, uint32_t events) {
601         Socket *s = SOCKET(u);
602
603         assert(s);
604
605         log_info("Incoming traffic on %s", unit_id(u));
606
607         if (events != POLLIN)
608                 socket_enter_stop_pre(s, false);
609
610         socket_enter_running(s);
611 }
612
613 static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
614         Socket *s = SOCKET(u);
615         bool success;
616
617         assert(s);
618         assert(pid >= 0);
619
620         success = code == CLD_EXITED || status == 0;
621         s->failure = s->failure || !success;
622
623         assert(s->control_pid == pid);
624         assert(s->control_command);
625
626         exec_status_fill(&s->control_command->exec_status, pid, code, status);
627         s->control_pid = 0;
628
629         log_debug("%s: control process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
630
631         if (s->control_command->command_next &&
632             (success || (s->state == SOCKET_EXEC_STOP_PRE || s->state == SOCKET_EXEC_STOP_POST)))
633                 socket_run_next(s, success);
634         else {
635                 /* No further commands for this step, so let's figure
636                  * out what to do next */
637
638                 switch (s->state) {
639
640                 case SOCKET_START_PRE:
641                         if (success)
642                                 socket_enter_start_pre(s);
643                         else
644                                 socket_enter_stop_pre(s, false);
645                         break;
646
647                 case SOCKET_START_POST:
648                         if (success)
649                                 socket_set_state(s, SOCKET_LISTENING);
650                         else
651                                 socket_enter_stop_pre(s, false);
652                         break;
653
654                 case SOCKET_STOP_PRE:
655                 case SOCKET_STOP_PRE_SIGTERM:
656                 case SOCKET_STOP_PRE_SIGKILL:
657                         socket_enter_stop_post(s, success);
658                         break;
659
660                 case SOCKET_STOP_POST:
661                 case SOCKET_STOP_POST_SIGTERM:
662                 case SOCKET_STOP_POST_SIGKILL:
663                         socket_enter_dead(s, success);
664                         break;
665
666                 default:
667                         assert_not_reached("Uh, control process died at wrong time.");
668                 }
669         }
670 }
671
672 static void socket_timer_event(Unit *u, int id, uint64_t elapsed) {
673         Socket *s = SOCKET(u);
674
675         assert(s);
676         assert(elapsed == 1);
677
678         assert(s->timer_id == id);
679
680         switch (s->state) {
681
682         case SOCKET_START_PRE:
683         case SOCKET_START_POST:
684                 log_warning("%s operation timed out. Stopping.", unit_id(u));
685                 socket_enter_stop_pre(s, false);
686                 break;
687
688         case SOCKET_STOP_PRE:
689                 log_warning("%s stopping timed out. Terminating.", unit_id(u));
690                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, false);
691                 break;
692
693         case SOCKET_STOP_PRE_SIGTERM:
694                 log_warning("%s stopping timed out. Killing.", unit_id(u));
695                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
696                 break;
697
698         case SOCKET_STOP_PRE_SIGKILL:
699                 log_warning("%s still around after SIGKILL. Ignoring.", unit_id(u));
700                 socket_enter_stop_post(s, false);
701                 break;
702
703         case SOCKET_STOP_POST:
704                 log_warning("%s stopping timed out (2). Terminating.", unit_id(u));
705                 socket_enter_signal(s, SOCKET_STOP_POST_SIGTERM, false);
706                 break;
707
708         case SOCKET_STOP_POST_SIGTERM:
709                 log_warning("%s stopping timed out (2). Killing.", unit_id(u));
710                 socket_enter_signal(s, SOCKET_STOP_POST_SIGKILL, false);
711                 break;
712
713         case SOCKET_STOP_POST_SIGKILL:
714                 log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", unit_id(u));
715                 socket_enter_dead(s, false);
716                 break;
717
718         default:
719                 assert_not_reached("Timeout at wrong time.");
720         }
721 }
722
723 int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
724         int *rfds;
725         unsigned rn_fds, k;
726         SocketPort *p;
727
728         assert(s);
729         assert(fds);
730         assert(n_fds);
731
732         /* Called from the service code for requesting our fds */
733
734         rn_fds = 0;
735         LIST_FOREACH(port, p, s->ports)
736                 if (p->fd >= 0)
737                         rn_fds++;
738
739         if (!(rfds = new(int, rn_fds)) < 0)
740                 return -ENOMEM;
741
742         k = 0;
743         LIST_FOREACH(port, p, s->ports)
744                 if (p->fd >= 0)
745                         rfds[k++] = p->fd;
746
747         assert(k == rn_fds);
748
749         *fds = rfds;
750         *n_fds = rn_fds;
751
752         return 0;
753 }
754
755 const UnitVTable socket_vtable = {
756         .suffix = ".socket",
757
758         .init = socket_init,
759         .done = socket_done,
760
761         .dump = socket_dump,
762
763         .start = socket_start,
764         .stop = socket_stop,
765
766         .active_state = socket_active_state,
767
768         .fd_event = socket_fd_event,
769         .sigchld_event = socket_sigchld_event,
770         .timer_event = socket_timer_event
771 };