forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enables the padding of QUIC handshake packets to the max packet size. Does not pad packets which do not leave enough space to fit a padding frame after expanding the final stream frame. An alternative would be to add a new type of padding frame which could show up earlier in the packet, but this is good enough for now. flag to enable the padding of QUIC handshake packets to full size Merge internal change: 55118010 Add a set_seed method to the PacketDroppingTestWriter to facilitate reproducing test behavior. Merge internal change: 55107501 Consistently pass the IsHandshake flag to the congestion control algorithm in QUIC. Merge internal change: 55046282 The goal is parity between HTTP and QUIC testing. Merge internal change: 55000555 Fixed comments - found while back porting changes to server. Merge internal change: 54999641 Fix bug in QuicPacketCreator's packet size calculation when a stream frame is close to the maximum possible. Merge internal change: 54933729 Remove unused random_reorder field from QuicPacketCreator::Options Merge internal change: 54885136 Using GFE's IOVector to replace uses of struct iovec on the QUIC's Write path. Merge internal change: 54805402 R=rch@chromium.org Review URL: https://codereview.chromium.org/46903002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231278 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
rtenneti@chromium.org
committed
Oct 28, 2013
1 parent
963eac2
commit 583bcbc
Showing
21 changed files
with
834 additions
and
283 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright 2013 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "net/quic/iovector.h" | ||
|
||
namespace net { | ||
|
||
IOVector::IOVector() {} | ||
|
||
IOVector::~IOVector() {} | ||
|
||
} // namespace net |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
// Copyright 2013 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef NET_QUIC_IOVECTOR_H_ | ||
#define NET_QUIC_IOVECTOR_H_ | ||
|
||
#include <stddef.h> | ||
#include <algorithm> | ||
#include <vector> | ||
|
||
#include "base/basictypes.h" | ||
#include "base/logging.h" | ||
#include "net/base/iovec.h" | ||
#include "net/base/net_export.h" | ||
|
||
namespace net { | ||
|
||
// Calculate the total number of bytes in an array of iovec structures. | ||
inline size_t TotalIovecLength(const struct iovec* iov, int iovcnt) { | ||
size_t length = 0; | ||
if (iov != NULL) { | ||
for (int i = 0; i < iovcnt; ++i) { | ||
length += iov[i].iov_len; | ||
} | ||
} | ||
return length; | ||
} | ||
|
||
// IOVector is a helper class that makes it easier to work with POSIX vector I/O | ||
// struct. It is a thin wrapper by design and thus has no virtual functions and | ||
// all inlined methods. This class makes no assumptions about the ordering of | ||
// the pointer values of the blocks appended, it simply counts bytes when asked | ||
// to consume bytes. | ||
// | ||
// IOVector is a bookkeeping object that collects a description of buffers to | ||
// be read or written together and in order. It does not take ownership of the | ||
// blocks appended. | ||
// | ||
// Because it is used for scatter-gather operations, the order in which the | ||
// buffer blocks are added to the IOVector is important to the client. The | ||
// intended usage pattern is: | ||
// | ||
// iovector.Append(p0, len0); | ||
// ... | ||
// iovector.Append(pn, lenn); | ||
// int bytes_written = writev(fd, iovector.iovec(), iovector.Size()); | ||
// if (bytes_written > 0) | ||
// iovector.Consume(bytes_written); | ||
// | ||
// The sequence is the same for readv, except that Consume() in this case is | ||
// used to change the IOVector to only keep track of description of blocks of | ||
// memory not yet written to. | ||
// | ||
// IOVector does not have any method to change the iovec entries that it | ||
// accumulates. This is due to the block merging nature of Append(): we'd like | ||
// to avoid accidentally change an entry that is assembled by two or more | ||
// Append()'s by simply an index access. | ||
// | ||
|
||
class NET_EXPORT_PRIVATE IOVector { | ||
public: | ||
// Provide a default constructor so it'll never be inhibited by adding other | ||
// constructors. | ||
IOVector(); | ||
~IOVector(); | ||
|
||
// Provides a way to convert system call-like iovec representation to | ||
// IOVector. | ||
void AppendIovec(const struct iovec* iov, int iovcnt) { | ||
for (int i = 0; i < iovcnt; ++i) | ||
Append(static_cast<char*>(iov[i].iov_base), iov[i].iov_len); | ||
} | ||
|
||
// Appends at most max_bytes from iovec to the IOVector. | ||
size_t AppendIovecAtMostBytes(const struct iovec* iov, | ||
int iovcnt, | ||
size_t max_bytes) { | ||
size_t bytes_appended = 0; | ||
for (int i = 0; i < iovcnt && max_bytes > 0; ++i) { | ||
const size_t length = std::min(max_bytes, iov[i].iov_len); | ||
Append(static_cast<char*>(iov[i].iov_base), length); | ||
max_bytes -= length; | ||
bytes_appended += length; | ||
} | ||
return bytes_appended; | ||
} | ||
|
||
// Append another block to the IOVector. Since IOVector can be used for read | ||
// and write, it always takes char*. Clients that writes will need to cast | ||
// away the constant of the pointer before appending a block. | ||
void Append(char* buffer, size_t length) { | ||
if (buffer != NULL && length > 0) { | ||
if (iovec_.size() > 0) { | ||
struct iovec& last = iovec_.back(); | ||
// If the new block is contiguous with the last block, just extend. | ||
if (static_cast<char*>(last.iov_base) + last.iov_len == buffer) { | ||
last.iov_len += length; | ||
return; | ||
} | ||
} | ||
struct iovec tmp = {buffer, length}; | ||
iovec_.push_back(tmp); | ||
} | ||
} | ||
|
||
// Same as Append, but doesn't do the tail merge optimization. | ||
// Intended for testing. | ||
void AppendNoCoalesce(char* buffer, size_t length) { | ||
if (buffer != NULL && length > 0) { | ||
struct iovec tmp = {buffer, length}; | ||
iovec_.push_back(tmp); | ||
} | ||
} | ||
|
||
// Remove a number of bytes from the beginning of the IOVector. Since vector | ||
// I/O operations always occur at the beginning of the block list, a method | ||
// to remove bytes at the end is not provided. | ||
// It returns the number of bytes actually consumed (it'll only be smaller | ||
// than the requested number if the IOVector contains less data). | ||
size_t Consume(size_t length) { | ||
if (length == 0) return 0; | ||
|
||
size_t bytes_to_consume = length; | ||
std::vector<struct iovec>::iterator iter = iovec_.begin(); | ||
std::vector<struct iovec>::iterator end = iovec_.end(); | ||
for (; iter < end && bytes_to_consume >= iter->iov_len; ++iter) { | ||
bytes_to_consume -= iter->iov_len; | ||
} | ||
iovec_.erase(iovec_.begin(), iter); | ||
if (iovec_.size() > 0 && bytes_to_consume != 0) { | ||
iovec_[0].iov_base = | ||
static_cast<char*>(iovec_[0].iov_base) + bytes_to_consume; | ||
iovec_[0].iov_len -= bytes_to_consume; | ||
return length; | ||
} | ||
if (iovec_.size() == 0 && bytes_to_consume > 0) { | ||
LOG(DFATAL) << "Attempting to consume " << bytes_to_consume | ||
<< " non-existent bytes."; | ||
} | ||
// At this point bytes_to_consume is the number of wanted bytes left over | ||
// after walking through all the iovec entries. | ||
return length - bytes_to_consume; | ||
} | ||
|
||
// TODO(joechan): If capacity is large, swap out for a blank one. | ||
// Clears the IOVector object to contain no blocks. | ||
void Clear() { iovec_.clear(); } | ||
|
||
// Swap the guts of two IOVector. | ||
void Swap(IOVector* other) { iovec_.swap(other->iovec_); } | ||
|
||
// Returns the number of valid blocks in the IOVector (not the number of | ||
// bytes). | ||
int Size() const { return iovec_.size(); } | ||
|
||
// Returns the total storage used by the IOVector in number of blocks (not | ||
// the number of bytes). | ||
int Capacity() const { return iovec_.capacity(); } | ||
|
||
// Returns true if there are no blocks in the IOVector. | ||
bool Empty() const { return iovec_.empty(); } | ||
|
||
// Returns the pointer to the beginning of the iovec to be used for vector | ||
// I/O operations. If the IOVector has no blocks appened, this function | ||
// returns NULL. | ||
struct iovec* iovec() { return !Empty() ? &iovec_[0] : NULL; } | ||
|
||
// Const version. | ||
const struct iovec* iovec() const { return !Empty() ? &iovec_[0] : NULL; } | ||
|
||
// Returns a pointer to one past the last byte of the last block. If the | ||
// IOVector is empty, NULL is returned. | ||
const char* LastBlockEnd() const { | ||
return iovec_.size() > 0 ? | ||
static_cast<char *>(iovec_.back().iov_base) + iovec_.back().iov_len : | ||
NULL; | ||
} | ||
|
||
// Returns the total number of bytes in the IOVector. | ||
size_t TotalBufferSize() const { return TotalIovecLength(iovec(), Size()); } | ||
|
||
void Resize(int count) { | ||
iovec_.resize(count); | ||
} | ||
|
||
private: | ||
std::vector<struct iovec> iovec_; | ||
|
||
// IOVector has value-semantics; copy and assignment are allowed. | ||
// This class does not explicitly define copy/move constructors or the | ||
// assignment operator to preserve compiler-generated copy/move constructors | ||
// and assignment operators. Note that since IOVector does not own the | ||
// actual buffers that the struct iovecs point to, copies and assignments | ||
// result in a shallow copy of the buffers; resulting IOVectors will point | ||
// to the same copy of the underlying data. | ||
}; | ||
|
||
} // namespace net | ||
|
||
#endif // NET_QUIC_IOVECTOR_H_ |
Oops, something went wrong.