15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/forwarder.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tools/android/forwarder2/socket.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace forwarder2 { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kBufferSize = 32 * 1024; 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class to buffer reads and writes from one socket to another. 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Each implements a small buffer connected two one input socket, and 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// one output socket. 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// socket_from_ ---> [BufferedCopier] ---> socket_to_ 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// These objects are used in a pair to handle duplex traffic, as in: 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ------> [BufferedCopier_1] ---> 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// / \ 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// socket_1 * * socket_2 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// \ / 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// <------ [BufferedCopier_2] <---- 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// When a BufferedCopier is in the READING state (see below), it only listens 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// to events on its input socket, and won't detect when its output socket 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// disconnects. To work around this, its peer will call its Close() method 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// when that happens. 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Forwarder::BufferedCopier { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Possible states: 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // READING - Empty buffer and Waiting for input. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // WRITING - Data in buffer, and waiting for output. 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CLOSING - Like WRITING, but do not try to read after that. 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CLOSED - Completely closed. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // State transitions are: 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T01: READING ---[receive data]---> WRITING 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T02: READING ---[error on input socket]---> CLOSED 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T03: READING ---[Close() call]---> CLOSED 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T04: WRITING ---[write partial data]---> WRITING 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T05: WRITING ---[write all data]----> READING 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T06: WRITING ---[error on output socket]----> CLOSED 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T07: WRITING ---[Close() call]---> CLOSING 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T08: CLOSING ---[write partial data]---> CLOSING 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T09: CLOSING ---[write all data]----> CLOSED 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T10: CLOSING ---[Close() call]---> CLOSING 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // T11: CLOSING ---[error on output socket] ---> CLOSED 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enum State { 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_READING = 0, 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_WRITING = 1, 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_CLOSING = 2, 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STATE_CLOSED = 3, 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Does NOT own the pointers. 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BufferedCopier(Socket* socket_from, Socket* socket_to) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : socket_from_(socket_from), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_to_(socket_to), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read_(0), 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_offset_(0), 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) peer_(NULL), 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_(STATE_READING) {} 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sets the 'peer_' field pointing to the other BufferedCopier in a pair. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SetPeer(BufferedCopier* peer) { 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!peer_); 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) peer_ = peer; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_closed() const { return state_ == STATE_CLOSED; } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Gently asks to close a buffer. Called either by the peer or the forwarder. 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Close() { 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (state_) { 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_READING: 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_CLOSED; // T03 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_WRITING: 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_CLOSING; // T07 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSING: 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; // T10 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSED: 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ; 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call this before select(). This updates |read_fds|, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |write_fds| and |max_fd| appropriately *if* the buffer isn't closed. 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PrepareSelect(fd_set* read_fds, fd_set* write_fds, int* max_fd) { 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int fd; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (state_) { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_READING: 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(bytes_read_ == 0); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(write_offset_ == 0); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fd = socket_from_->fd(); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T02 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FD_SET(fd, read_fds); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_WRITING: 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSING: 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(bytes_read_ > 0); 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(write_offset_ < bytes_read_); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fd = socket_to_->fd(); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) { 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T06 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FD_SET(fd, write_fds); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSED: 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *max_fd = std::max(*max_fd, fd); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Call this after a select() call to operate over the buffer. 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ProcessSelect(const fd_set& read_fds, const fd_set& write_fds) { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int fd, ret; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (state_) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_READING: 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fd = socket_from_->fd(); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_CLOSED; // T02 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!FD_ISSET(fd, &read_fds)) 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ret = socket_from_->NonBlockingRead(buffer_, kBufferSize); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ret <= 0) { 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T02 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bytes_read_ = ret; 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_offset_ = 0; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_WRITING; // T01 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_WRITING: 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSING: 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fd = socket_to_->fd(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) { 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T06 + T11 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!FD_ISSET(fd, &write_fds)) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ret = socket_to_->NonBlockingWrite(buffer_ + write_offset_, 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bytes_read_ - write_offset_); 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ret <= 0) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T06 + T11 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) write_offset_ += ret; 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (write_offset_ < bytes_read_) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // T08 + T04 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_offset_ = 0; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read_ = 0; 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (state_ == STATE_CLOSING) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForceClose(); // T09 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_READING; // T05 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case STATE_CLOSED: 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Internal method used to close the buffer and notify the peer, if any. 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void ForceClose() { 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (peer_) { 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) peer_->Close(); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) peer_ = NULL; 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_ = STATE_CLOSED; 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not owned. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Socket* socket_from_; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Socket* socket_to_; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read_; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_offset_; 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BufferedCopier* peer_; 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) State state_; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buffer_[kBufferSize]; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BufferedCopier); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Forwarder::Forwarder(scoped_ptr<Socket> socket1, 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<Socket> socket2) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : socket1_(socket1.Pass()), 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) socket2_(socket2.Pass()), 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer1_(new BufferedCopier(socket1_.get(), socket2_.get())), 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer2_(new BufferedCopier(socket2_.get(), socket1_.get())) { 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer1_->SetPeer(buffer2_.get()); 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer2_->SetPeer(buffer1_.get()); 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Forwarder::~Forwarder() { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Forwarder::RegisterFDs(fd_set* read_fds, fd_set* write_fds, int* max_fd) { 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer1_->PrepareSelect(read_fds, write_fds, max_fd); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer2_->PrepareSelect(read_fds, write_fds, max_fd); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Forwarder::ProcessEvents(const fd_set& read_fds, const fd_set& write_fds) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer1_->ProcessSelect(read_fds, write_fds); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer2_->ProcessSelect(read_fds, write_fds); 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Forwarder::IsClosed() const { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return buffer1_->is_closed() && buffer2_->is_closed(); 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Forwarder::Shutdown() { 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer1_->Close(); 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer2_->Close(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace forwarder2 256