Line data Source code
1 : #include "../../../burp.h"
2 : #include "../../../alloc.h"
3 : #include "../../../asfd.h"
4 : #include "../../../async.h"
5 : #include "../../../cmd.h"
6 : #include "../../../conf.h"
7 : #include "../../../fsops.h"
8 : #include "../../../lock.h"
9 : #include "../../../log.h"
10 : #include "../../../prepend.h"
11 : #include "champ_client.h"
12 : #include "champ_chooser.h"
13 : #include "champ_server.h"
14 :
15 : #include <sys/un.h>
16 :
17 0 : static int champ_chooser_fork(struct sdirs *sdirs, struct conf **confs)
18 : {
19 0 : pid_t childpid=-1;
20 :
21 0 : if(!get_int(confs[OPT_FORK]))
22 : {
23 0 : logp("Not forking a champ chooser process.\n");
24 : // They need to manually run a separate process.
25 0 : return 0;
26 : }
27 :
28 0 : switch((childpid=fork()))
29 : {
30 : case -1:
31 : logp("fork failed in %s: %s\n",
32 0 : __func__, strerror(errno));
33 0 : return -1;
34 : case 0:
35 : // Child.
36 : int cret;
37 0 : log_fzp_set(NULL, confs);
38 0 : switch(champ_chooser_server(sdirs, confs))
39 : {
40 : case 0:
41 : cret=0;
42 : break;
43 : default:
44 0 : cret=1;
45 0 : break;
46 : }
47 0 : exit(cret);
48 : default:
49 : // Parent.
50 0 : logp("forked champ chooser pid %d\n", childpid);
51 0 : return 0;
52 : }
53 : return -1; // Not reached.
54 : }
55 :
56 0 : static int connect_to_champ_chooser(struct sdirs *sdirs, struct conf **confs)
57 : {
58 : int len;
59 0 : int s=-1;
60 0 : int tries=0;
61 0 : int tries_max=3;
62 : struct sockaddr_un remote;
63 :
64 0 : if(!lock_test(sdirs->champlock))
65 : {
66 : // Champ chooser is not running.
67 : // Try to fork a new champ chooser process.
68 0 : if(champ_chooser_fork(sdirs, confs)) return -1;
69 : }
70 :
71 : // Champ chooser should either be running now, or about to run.
72 :
73 0 : if((s=socket(AF_UNIX, SOCK_STREAM, 0))<0)
74 : {
75 0 : logp("socket error in %s: %s\n", __func__, strerror(errno));
76 0 : return -1;
77 : }
78 :
79 : memset(&remote, 0, sizeof(struct sockaddr_un));
80 0 : remote.sun_family=AF_UNIX;
81 : snprintf(remote.sun_path, sizeof(remote.sun_path),
82 0 : "%s", sdirs->champsock);
83 0 : len=strlen(remote.sun_path)+sizeof(remote.sun_family)+1;
84 :
85 0 : while(tries++<tries_max)
86 : {
87 0 : int sleeptimeleft=3;
88 0 : if(!connect(s, (struct sockaddr *)&remote, len))
89 : {
90 0 : logp("Connected to champ chooser.\n");
91 0 : return s;
92 : }
93 :
94 : // SIGCHLDs may be interrupting.
95 : sleeptimeleft=3;
96 0 : while(sleeptimeleft>0) sleeptimeleft=sleep(sleeptimeleft);
97 : }
98 :
99 : // Only log any error after all attempts failed, to make the logs
100 : // less worrying (most of the time, the first attempt will fail).
101 : logp("Could not connect to champ chooser on %s after %d attempts: %s\n",
102 0 : sdirs->champsock, tries_max, strerror(errno));
103 :
104 0 : return -1;
105 : }
106 :
107 0 : struct asfd *champ_chooser_connect(struct async *as,
108 : struct sdirs *sdirs, struct conf **confs)
109 : {
110 0 : int champsock=-1;
111 0 : char *champname=NULL;
112 0 : struct asfd *chfd=NULL;
113 0 : const char *cname=NULL;
114 :
115 : // Connect to champ chooser now.
116 : // This may start up a new champ chooser. On a machine with multiple
117 : // cores, it may be faster to do now, way before it is actually needed
118 : // in phase2.
119 0 : if((champsock=connect_to_champ_chooser(sdirs, confs))<0)
120 : {
121 0 : logp("could not connect to champ chooser\n");
122 0 : goto error;
123 : }
124 :
125 0 : if(!(chfd=setup_asfd(as, "champ chooser socket", &champsock, NULL,
126 : ASFD_STREAM_STANDARD, ASFD_FD_SERVER_TO_CHAMP_CHOOSER, -1,
127 0 : confs))) goto error;
128 :
129 0 : cname=get_string(confs[OPT_CNAME]);
130 0 : if(!(champname=prepend_n("cname", cname, strlen(cname), ":")))
131 : goto error;
132 :
133 0 : if(chfd->write_str(chfd, CMD_GEN, champname)
134 0 : || asfd_read_expect(chfd, CMD_GEN, "cname ok"))
135 : goto error;
136 :
137 0 : free_w(&champname);
138 0 : return chfd;
139 : error:
140 0 : free_w(&champname);
141 0 : as->asfd_remove(as, chfd);
142 0 : asfd_free(&chfd);
143 0 : close_fd(&champsock);
144 0 : return NULL;
145 : }
|