~ubuntu-branches/ubuntu/trusty/bip/trusty-proposed

« back to all changes in this revision

Viewing changes to src/connection.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Cornet
  • Date: 2009-08-24 19:20:53 UTC
  • mfrom: (1.1.9 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20090824192053-cw134dkjpm5h9fy8
* New Upstream Version (Closes: #542291).
* Fix debhelper 7 dependency version.
* Add README.source
* Bump standards-version, no change needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
                list_free(cn->incoming_lines);
76
76
        if (cn->incoming)
77
77
                free(cn->incoming);
78
 
        if (cn->ip_list)
79
 
                list_free(cn->ip_list);
80
78
        if (cn->connecting_data)
81
79
                connecting_data_free(cn->connecting_data);
82
80
        /* conn->user_data */
232
230
{
233
231
        size_t size;
234
232
        size_t tcount = 0;
235
 
        size_t p_tcount = 0;
236
233
        ssize_t count;
237
234
 
238
235
        size = strlen(message);
 
236
        if (size == 0)
 
237
                return WRITE_OK;
 
238
        /* loop if we wrote some data but not everything, or if error is
 
239
         * EINTR */
239
240
        do {
240
 
                while ((count = write(cn->handle,
241
 
                                        ((const char *)message) + tcount,
242
 
                                        size - tcount)) > 0) {
 
241
                count = write(cn->handle, ((const char *)message) + tcount,
 
242
                                        size - tcount);
 
243
                if (count > 0) {
243
244
                        tcount += count;
244
245
                        if (tcount == size)
245
 
                                break;
246
 
                        if (tcount - p_tcount == 0) {
247
 
                                /* no write at all, we give up */
248
 
                                cn->connected = CONN_ERROR;
249
 
                                return WRITE_ERROR;
250
 
                        }
251
 
                        p_tcount = tcount;
252
 
                }
253
 
        } while (count < 0 &&
254
 
                (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS));
255
 
 
256
 
#if 0
257
 
        if (count <= 0 && tcount > 0)
258
 
                fatal("shit happens errno:%d count:%d tcount:%d (%s)\n", errno,
259
 
                                count, tcount, message);
260
 
#endif
261
 
        if (count <= 0) {
262
 
                /*
263
 
                 * if no fatal error, return WRITE_KEEP, which makes caller
264
 
                 * keep line in its FIFO
265
 
                 *
266
 
                 * Cannot do: we might have written a partial line
267
 
                 * 
268
 
                if (errno == EAGAIN || errno == EINTR || errno == EINPROGRESS)
269
 
                        return WRITE_KEEP;
270
 
                 */
271
 
 
272
 
                if (cn_is_connected(cn)) {
273
 
                        mylog(LOG_DEBUGVERB, "write(fd %d) : %s", cn->handle,
274
 
                                        strerror(errno));
275
 
                        cn->connected = CONN_ERROR;
276
 
                }
277
 
                mylog(LOG_DEBUGVERB, "write : %s", strerror(errno));
278
 
                return WRITE_ERROR;
279
 
        }
280
 
        mylog(LOG_DEBUGVERB, "%d/%d bytes sent !", tcount, size);
281
 
        return WRITE_OK;
 
246
                                return WRITE_OK;
 
247
                }
 
248
        } while (count > 0 || (count < 0 && errno == EINTR));
 
249
 
 
250
        /* If we reach this point, we have a partial write */
 
251
        assert(count != 0);
 
252
 
 
253
        /* if no fatal error, return WRITE_KEEP, which makes caller keep line
 
254
         * in its FIFO
 
255
         *
 
256
         * Shitty: we might have written a partial line, so we hack the line...
 
257
         * Callers of _write_socket muse provide a writable message
 
258
         */
 
259
        if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) {
 
260
                memmove(message, message + tcount, size - tcount + 1);
 
261
                return WRITE_KEEP;
 
262
        }
 
263
        /* other errors, EPIPE or worse, close the connection, repport error */
 
264
        if (cn_is_connected(cn)) {
 
265
                if (errno != EPIPE)
 
266
                        mylog(LOG_INFO, "Broken socket: %s.", strerror(errno));
 
267
                connection_close(cn);
 
268
                cn->connected = CONN_ERROR;
 
269
        }
 
270
        mylog(LOG_DEBUGVERB, "write: %d, %s", cn->handle, strerror(errno));
 
271
        return WRITE_ERROR;
282
272
}
283
273
 
284
274
static int write_socket(connection_t *cn, char *line)
301
291
        if (cn == NULL)
302
292
                fatal("real_write_all: wrong arguments");
303
293
 
304
 
        while ((line = list_remove_first(cn->outgoing))) {
 
294
        if (cn->partial) {
 
295
                line = cn->partial;
 
296
                cn->partial = NULL;
 
297
        } else {
 
298
                line = list_remove_first(cn->outgoing);
 
299
        }
 
300
 
 
301
        do {
305
302
                ret = write_socket(cn, line);
306
303
 
307
304
                switch (ret) {
311
308
                        return 1;
312
309
                case WRITE_KEEP:
313
310
                        /* interrupted or not ready */
314
 
                        list_add_first(cn->outgoing, line);
 
311
                        assert(cn->partial == NULL);
 
312
                        cn->partial = line;
315
313
                        return 0;
316
314
                case WRITE_OK:
317
315
                        free(line);
324
322
                if (cn->anti_flood)
325
323
                        /* one line at a time */
326
324
                        break;
327
 
        }
 
325
        } while ((line = list_remove_first(cn->outgoing)));
328
326
        return 0;
329
327
}
330
328
 
331
329
void write_line_fast(connection_t *cn, char *line)
332
330
{
333
331
        int r;
334
 
        r = write_socket(cn, line);
335
 
        switch (r) {
336
 
        case WRITE_KEEP:
337
 
                list_add_first(cn->outgoing, bip_strdup(line));
338
 
                break;
339
 
        case WRITE_ERROR:
340
 
                cn->connected = CONN_ERROR;
341
 
                break;
342
 
        case WRITE_OK:
343
 
                break;
344
 
        default:
345
 
                fatal("internal error 7");
346
 
                break;
 
332
        char *nline = bip_strdup(line);
 
333
 
 
334
        if (cn->partial) {
 
335
                list_add_first(cn->outgoing, nline);
 
336
        } else {
 
337
                r = write_socket(cn, nline);
 
338
                switch (r) {
 
339
                case WRITE_KEEP:
 
340
                        cn->partial = nline;
 
341
                        break;
 
342
                case WRITE_ERROR:
 
343
                case WRITE_OK:
 
344
                        free(nline);
 
345
                        break;
 
346
                default:
 
347
                        fatal("internal error 7");
 
348
                        break;
 
349
                }
347
350
        }
348
351
}
349
352
 
350
353
void write_lines(connection_t *cn, list_t *lines)
351
354
{
352
355
        list_append(cn->outgoing, lines);
 
356
        real_write_all(cn);
353
357
}
354
358
 
355
359
void write_line(connection_t *cn, char *line)
356
360
{
357
361
        list_add_last(cn->outgoing, bip_strdup(line));
 
362
        real_write_all(cn);
358
363
}
359
364
 
360
365
list_t *read_lines(connection_t *cn, int *error)
1021
1026
        conn->listening = listen;
1022
1027
        conn->handle = -1;
1023
1028
        conn->client = 0;
1024
 
        conn->ip_list = NULL;
1025
1029
        conn->connecting_data = NULL;
1026
1030
#ifdef HAVE_LIBSSL
1027
1031
        conn->ssl_ctx_h = NULL;
1278
1282
 
1279
1283
        /* in basic mode (mode 1), accept a leaf certificate if we can find it
1280
1284
         * in the store */
1281
 
        if (c->ssl_check_mode == SSL_CHECK_BASIC && depth == 0 && result == 0 &&
 
1285
        if (c->ssl_check_mode == SSL_CHECK_BASIC && result == 0 &&
1282
1286
                        (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ||
1283
1287
                         err == X509_V_ERR_CERT_UNTRUSTED ||
1284
1288
                         err == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE ||
1285
1289
                         err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
1286
 
                         err == X509_V_ERR_CERT_HAS_EXPIRED)) {
 
1290
                         err == X509_V_ERR_CERT_HAS_EXPIRED ||
 
1291
                         err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN)) {
1287
1292
 
1288
1293
                if (X509_STORE_get_by_subject(ctx, X509_LU_X509,
1289
1294
                                X509_get_subject_name(err_cert), &xobj) > 0 &&
1440
1445
        case SSL_CHECK_BASIC:
1441
1446
                SSL_CTX_set_verify(conn->ssl_ctx_h, SSL_VERIFY_PEER,
1442
1447
                                bip_ssl_verify_callback);
1443
 
                SSL_CTX_set_verify_depth(conn->ssl_ctx_h, 0);
 
1448
                /* SSL_CTX_set_verify_depth(conn->ssl_ctx_h, 0); */
1444
1449
                break;
1445
1450
        case SSL_CHECK_CA:
1446
1451
                SSL_CTX_set_verify(conn->ssl_ctx_h, SSL_VERIFY_PEER,