~yadi/squid/parser-ng-bug2043

« back to all changes in this revision

Viewing changes to src/tunnel.cc

  • Committer: Amos Jeffries
  • Date: 2015-02-28 00:40:23 UTC
  • mfrom: (13924.1.33 trunk)
  • Revision ID: squid3@treenet.co.nz-20150228004023-1bv4uyhwp3n3d57w
Merged from trunk rev.13957

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#include "acl/FilledChecklist.h"
13
13
#include "base/CbcPointer.h"
14
14
#include "CachePeer.h"
 
15
#include "cbdata.h"
15
16
#include "client_side.h"
16
17
#include "client_side_request.h"
17
18
#include "comm.h"
115
116
    {
116
117
 
117
118
    public:
118
 
        Connection() : len (0), buf ((char *)xmalloc(SQUID_TCP_SO_RCVBUF)), size_ptr(NULL) {}
 
119
        Connection() : len (0), buf ((char *)xmalloc(SQUID_TCP_SO_RCVBUF)), size_ptr(NULL), delayedLoops(0),
 
120
            readPending(NULL), readPendingFunc(NULL) {}
119
121
 
120
122
        ~Connection();
121
123
 
137
139
        int64_t *size_ptr;      /* pointer to size in an ConnStateData for logging */
138
140
 
139
141
        Comm::ConnectionPointer conn;    ///< The currently connected connection.
 
142
        uint8_t delayedLoops; ///< how many times a read on this connection has been postponed.
140
143
 
 
144
        // XXX: make these an AsyncCall when event API can handle them
 
145
        TunnelStateData *readPending;
 
146
        EVH *readPendingFunc;
141
147
    private:
142
148
#if USE_DELAY_POOLS
143
149
 
210
216
static CLCB tunnelClientClosed;
211
217
static CTCB tunnelTimeout;
212
218
static PSC tunnelPeerSelectComplete;
 
219
static EVH tunnelDelayedClientRead;
 
220
static EVH tunnelDelayedServerRead;
213
221
static void tunnelConnected(const Comm::ConnectionPointer &server, void *);
214
222
static void tunnelRelayConnectRequest(const Comm::ConnectionPointer &server, void *);
215
223
 
262
270
    connectReqWriting(false)
263
271
{
264
272
    debugs(26, 3, "TunnelStateData constructed this=" << this);
 
273
    client.readPendingFunc = &tunnelDelayedClientRead;
 
274
    server.readPendingFunc = &tunnelDelayedServerRead;
265
275
}
266
276
 
267
277
TunnelStateData::~TunnelStateData()
275
285
 
276
286
TunnelStateData::Connection::~Connection()
277
287
{
 
288
    if (readPending)
 
289
        eventDelete(readPendingFunc, readPending);
 
290
 
278
291
    safe_free(buf);
279
292
}
280
293
 
331
344
TunnelStateData::readServer(char *, size_t len, Comm::Flag errcode, int xerrno)
332
345
{
333
346
    debugs(26, 3, HERE << server.conn << ", read " << len << " bytes, err=" << errcode);
 
347
    server.delayedLoops=0;
334
348
 
335
349
    /*
336
350
     * Bail out early on Comm::ERR_CLOSING
476
490
TunnelStateData::readClient(char *, size_t len, Comm::Flag errcode, int xerrno)
477
491
{
478
492
    debugs(26, 3, HERE << client.conn << ", read " << len << " bytes, err=" << errcode);
 
493
    client.delayedLoops=0;
479
494
 
480
495
    /*
481
496
     * Bail out early on Comm::ERR_CLOSING
676
691
        conn->close();
677
692
}
678
693
 
 
694
static void
 
695
tunnelDelayedClientRead(void *data)
 
696
{
 
697
    if (!data)
 
698
        return;
 
699
    TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
 
700
    if (!tunnel)
 
701
        return;
 
702
    tunnel->client.readPending = NULL;
 
703
    static uint64_t counter=0;
 
704
    debugs(26, 7, "Client read(2) delayed " << ++counter << " times");
 
705
    tunnel->copyRead(tunnel->client, TunnelStateData::ReadClient);
 
706
}
 
707
 
 
708
static void
 
709
tunnelDelayedServerRead(void *data)
 
710
{
 
711
    if (!data)
 
712
        return;
 
713
    TunnelStateData *tunnel = static_cast<TunnelStateData*>(data);
 
714
    if (!tunnel)
 
715
        return;
 
716
    tunnel->server.readPending = NULL;
 
717
    static uint64_t counter=0;
 
718
    debugs(26, 7, "Server read(2) delayed " << ++counter << " times");
 
719
    tunnel->copyRead(tunnel->server, TunnelStateData::ReadServer);
 
720
}
 
721
 
679
722
void
680
723
TunnelStateData::copyRead(Connection &from, IOCB *completion)
681
724
{
682
725
    assert(from.len == 0);
 
726
    // If only the minimum permitted read size is going to be attempted
 
727
    // then we schedule an event to try again in a few I/O cycles.
 
728
    // Allow at least 1 byte to be read every (0.3*10) seconds.
 
729
    int bw = from.bytesWanted(1, SQUID_TCP_SO_RCVBUF);
 
730
    if (bw == 1 && ++from.delayedLoops < 10) {
 
731
        from.readPending = this;
 
732
        eventAdd("tunnelDelayedServerRead", from.readPendingFunc, from.readPending, 0.3, true);
 
733
        return;
 
734
    }
 
735
 
683
736
    AsyncCall::Pointer call = commCbCall(5,4, "TunnelBlindCopyReadHandler",
684
737
                                         CommIoCbPtrFun(completion, this));
685
 
    comm_read(from.conn, from.buf, from.bytesWanted(1, SQUID_TCP_SO_RCVBUF), call);
 
738
    comm_read(from.conn, from.buf, bw, call);
686
739
}
687
740
 
688
741
void
965
1018
 
966
1019
#if USE_OPENSSL
967
1020
    if (CachePeer *p = srv->getPeer()) {
968
 
        if (p->use_ssl) {
 
1021
        if (p->secure.encryptTransport) {
969
1022
            AsyncCall::Pointer callback = asyncCall(5,4,
970
1023
                                                    "TunnelStateData::ConnectedToPeer",
971
1024
                                                    MyAnswerDialer(&TunnelStateData::connectedToPeer, this));