~ubuntu-branches/ubuntu/vivid/sslh/vivid-proposed

« back to all changes in this revision

Viewing changes to sslh-select.c

  • Committer: Package Import Robot
  • Author(s): Guillaume Delacour
  • Date: 2014-08-07 00:06:06 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140807000606-y1tg7j8i5t7d4drr
Tags: 1.16-1
* New upstream release: fix some startup problem when interfaces are not
  ready at boot time (IP_FREEBIND support when available) and can use libcap
  for transparent mode
* Enable libcap and libwrap support at build time
* Enable dpkg-buildflags: Drop hardening-wrapper Build-Depends and use
  DEB_BUILD_HARDENING instead of DEB_BUILD_MAINT_OPTIONS
* Remove old .gitignore as upstream has one too
* debian/sslh.tmpfile: Create /run/sslh for systemd as root because sslh
  write its pid before dropping privileges (Closes: #740560)
* debian/patches/disable_ip_freebind_test.diff: Remove "Can't bind address"
  upstream test because IP_FREEBIND is now enabled upstream
* debian/docs: upstream README is now README.md
* debian/rules:
  + use DESTDIR in addition of PREFIX as upstream change Makefile
* Refresh debian/patches/disable_valgrind_launch.diff due to upstream
  changes
* Stop service in case of purge (to be able to remove the user too)
* Use DEB_BUILD_OPTIONS to speed the build
* debian/patches/fixed_version.diff: Fix the version of binaries based on
  debian/changelog (instead of relying on git)
* Update Description as sslh is not only a ssl/ssh multiplexer but a
  protocol multiplexer

Show diffs side-by-side

added added

removed removed

Lines of Context:
64
64
            close(cnx->q[i].fd);
65
65
            FD_CLR(cnx->q[i].fd, fds);
66
66
            FD_CLR(cnx->q[i].fd, fds2);
67
 
            if (cnx->q[i].defered_data)
68
 
                free(cnx->q[i].defered_data);
 
67
            if (cnx->q[i].deferred_data)
 
68
                free(cnx->q[i].deferred_data);
69
69
        }
70
70
    }
71
71
    init_cnx(cnx);
129
129
 
130
130
 
131
131
/* Connect queue 1 of connection to SSL; returns new file descriptor */
132
 
int connect_queue(struct connection *cnx, struct addrinfo *addr, 
133
 
                  const char* cnx_name,
134
 
                  fd_set *fds_r, fd_set *fds_w)
 
132
int connect_queue(struct connection *cnx, fd_set *fds_r, fd_set *fds_w)
135
133
{
136
134
    struct queue *q = &cnx->q[1];
137
135
 
138
 
    q->fd = connect_addr(addr, cnx->q[0].fd, cnx_name);
 
136
    q->fd = connect_addr(cnx, cnx->q[0].fd);
139
137
    if ((q->fd != -1) && fd_is_in_range(q->fd)) {
140
138
        log_connection(cnx);
141
139
        set_nonblock(q->fd);
142
 
        flush_defered(q);
143
 
        if (q->defered_data) {
 
140
        flush_deferred(q);
 
141
        if (q->deferred_data) {
144
142
            FD_SET(q->fd, fds_w);
145
143
        } else {
146
144
            FD_SET(q->fd, fds_r);
190
188
}
191
189
 
192
190
/* Main loop: the idea is as follow:
193
 
 * - fds_r and fds_w contain the file descritors to monitor in read and write
 
191
 * - fds_r and fds_w contain the file descriptors to monitor in read and write
194
192
 * - When a file descriptor goes off, process it: read from it, write the data
195
193
 * to its corresponding pair.
196
194
 * - When a file descriptor blocks when writing, remove the read fd from fds_r,
197
 
 * move the data to a defered buffer, and add the write fd to fds_w. Defered
 
195
 * move the data to a deferred buffer, and add the write fd to fds_w. Defered
198
196
 * buffer is allocated dynamically.
199
 
 * - When we can write to a file descriptor that has defered data, we try to
 
197
 * - When we can write to a file descriptor that has deferred data, we try to
200
198
 * write as much as we can. Once all data is written, remove the fd from fds_w
201
199
 * and add its corresponding pair to fds_r, free the buffer.
202
200
 *
210
208
    struct timeval tv;
211
209
    int max_fd, in_socket, i, j, res;
212
210
    struct connection *cnx;
213
 
    struct proto *prot;
214
211
    int num_cnx;  /* Number of connections in *cnx */
215
212
    int num_probing = 0; /* Number of connections currently probing 
216
213
                          * We use this to know if we need to time out of
268
265
            if (cnx[i].q[0].fd != -1) {
269
266
                for (j = 0; j < 2; j++) {
270
267
                    if (is_fd_active(cnx[i].q[j].fd, &writefds)) {
271
 
                        res = flush_defered(&cnx[i].q[j]);
 
268
                        res = flush_deferred(&cnx[i].q[j]);
272
269
                        if ((res == -1) && ((errno == EPIPE) || (errno == ECONNRESET))) {
273
270
                            if (cnx[i].state == ST_PROBING) num_probing--;
274
271
                            tidy_connection(&cnx[i], &fds_r, &fds_w);
275
272
                            if (verbose)
276
273
                                fprintf(stderr, "closed slot %d\n", i);
277
274
                        } else {
278
 
                            /* If no defered data is left, stop monitoring the fd 
 
275
                            /* If no deferred data is left, stop monitoring the fd 
279
276
                             * for write, and restart monitoring the other one for reads*/
280
 
                            if (!cnx[i].q[j].defered_data_size) {
 
277
                            if (!cnx[i].q[j].deferred_data_size) {
281
278
                                FD_CLR(cnx[i].q[j].fd, &fds_w);
282
279
                                FD_SET(cnx[i].q[1-j].fd, &fds_r);
283
280
                            }
303
300
                            dump_connection(&cnx[i]);
304
301
                            exit(1);
305
302
                        }
306
 
                        num_probing--;
307
 
                        cnx[i].state = ST_SHOVELING;
308
303
 
309
304
                        /* If timed out it's SSH, otherwise the client sent
310
305
                         * data so probe the protocol */
311
306
                        if ((cnx[i].probe_timeout < time(NULL))) {
312
 
                            prot = timeout_protocol();
 
307
                            cnx[i].proto = timeout_protocol();
313
308
                        } else {
314
 
                            prot = probe_client_protocol(&cnx[i]);
 
309
                            res = probe_client_protocol(&cnx[i]);
 
310
                            if (res == PROBE_AGAIN)
 
311
                                continue;
315
312
                        }
316
313
 
 
314
                        num_probing--;
 
315
                        cnx[i].state = ST_SHOVELING;
 
316
 
317
317
                        /* libwrap check if required for this protocol */
318
 
                        if (prot->service && 
319
 
                            check_access_rights(in_socket, prot->service)) {
 
318
                        if (cnx[i].proto->service &&
 
319
                            check_access_rights(in_socket, cnx[i].proto->service)) {
320
320
                            tidy_connection(&cnx[i], &fds_r, &fds_w);
321
321
                            res = -1;
322
322
                        } else {
323
 
                            res = connect_queue(&cnx[i], 
324
 
                                                prot->saddr, 
325
 
                                                prot->description, 
326
 
                                                &fds_r, &fds_w);
 
323
                            res = connect_queue(&cnx[i], &fds_r, &fds_w);
327
324
                        }
328
325
 
329
326
                        if (res >= max_fd)