| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" |
| 6 |
| 7 #if defined(OS_WIN) |
| 5 // winsock2.h must be included first in order to ensure it is included before | 8 // winsock2.h must be included first in order to ensure it is included before |
| 6 // windows.h. | 9 // windows.h. |
| 7 #include <winsock2.h> | 10 #include <winsock2.h> |
| 11 #elif defined(OS_POSIX) |
| 12 #include <errno.h> |
| 13 #include <sys/socket.h> |
| 14 #include "base/message_loop.h" |
| 15 #include "net/base/net_errors.h" |
| 16 #include "third_party/libevent/event.h" |
| 17 #include "base/message_pump_libevent.h" |
| 18 #endif |
| 8 | 19 |
| 9 #include "net/base/telnet_server.h" | 20 #include "net/base/telnet_server.h" |
| 10 | 21 |
| 11 #define READ_BUF_SIZE 200 | 22 #if defined(OS_POSIX) |
| 23 // Used same name as in Windows to avoid #ifdef where refrenced |
| 24 #define SOCKET int |
| 25 const int INVALID_SOCKET = -1; |
| 26 const int SOCKET_ERROR = -1; |
| 27 struct event; // From libevent |
| 28 #endif |
| 29 |
| 30 const int kReadBufSize = 200; |
| 12 | 31 |
| 13 // Telnet protocol constants. | 32 // Telnet protocol constants. |
| 14 class TelnetProtocol { | 33 class TelnetProtocol { |
| 15 public: | 34 public: |
| 16 // Telnet command definitions (from arpa/telnet.h). | 35 // Telnet command definitions (from arpa/telnet.h). |
| 17 enum Commands { | 36 enum Commands { |
| 18 IAC = 255, // Interpret as command. | 37 IAC = 255, // Interpret as command. |
| 19 DONT = 254, // You are not to use option. | 38 DONT = 254, // You are not to use option. |
| 20 DO = 253, // Please, you use option. | 39 DO = 253, // Please, you use option. |
| 21 WONT = 252, // I won't use option. | 40 WONT = 252, // I won't use option. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 ListenSocket::SendInternal(data + begin_index, len - begin_index); | 121 ListenSocket::SendInternal(data + begin_index, len - begin_index); |
| 103 } | 122 } |
| 104 | 123 |
| 105 void TelnetServer::Accept() { | 124 void TelnetServer::Accept() { |
| 106 SOCKET conn = ListenSocket::Accept(socket_); | 125 SOCKET conn = ListenSocket::Accept(socket_); |
| 107 if (conn == INVALID_SOCKET) { | 126 if (conn == INVALID_SOCKET) { |
| 108 // TODO | 127 // TODO |
| 109 } else { | 128 } else { |
| 110 scoped_refptr<TelnetServer> sock = | 129 scoped_refptr<TelnetServer> sock = |
| 111 new TelnetServer(conn, socket_delegate_); | 130 new TelnetServer(conn, socket_delegate_); |
| 112 | 131 #if defined(OS_POSIX) |
| 132 sock->WatchSocket(WAITING_READ); |
| 133 #endif |
| 113 // Setup the way we want to communicate | 134 // Setup the way we want to communicate |
| 114 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::ECHO); | 135 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::ECHO); |
| 115 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::NAWS); | 136 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::NAWS); |
| 116 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::LFLOW); | 137 sock->SendIAC(TelnetProtocol::DO, TelnetProtocol::LFLOW); |
| 117 sock->SendIAC(TelnetProtocol::WILL, TelnetProtocol::ECHO); | 138 sock->SendIAC(TelnetProtocol::WILL, TelnetProtocol::ECHO); |
| 118 sock->SendIAC(TelnetProtocol::WILL, TelnetProtocol::SGA); | 139 sock->SendIAC(TelnetProtocol::WILL, TelnetProtocol::SGA); |
| 119 | 140 |
| 120 // it's up to the delegate to AddRef if it wants to keep it around | 141 // it's up to the delegate to AddRef if it wants to keep it around |
| 121 socket_delegate_->DidAccept(this, sock); | 142 socket_delegate_->DidAccept(this, sock); |
| 122 } | 143 } |
| 123 } | 144 } |
| 124 | 145 |
| 125 TelnetServer* TelnetServer::Listen(std::string ip, int port, | 146 TelnetServer* TelnetServer::Listen(std::string ip, int port, |
| 126 ListenSocketDelegate *del) { | 147 ListenSocketDelegate *del) { |
| 127 SOCKET s = ListenSocket::Listen(ip, port); | 148 SOCKET s = ListenSocket::Listen(ip, port); |
| 128 if (s == INVALID_SOCKET) { | 149 if (s == INVALID_SOCKET) { |
| 129 // TODO | 150 // TODO (ibrar): error handling |
| 130 } else { | 151 } else { |
| 131 TelnetServer *serv = new TelnetServer(s, del); | 152 TelnetServer *serv = new TelnetServer(s, del); |
| 132 serv->Listen(); | 153 serv->Listen(); |
| 133 return serv; | 154 return serv; |
| 134 } | 155 } |
| 135 return NULL; | 156 return NULL; |
| 136 } | 157 } |
| 137 | 158 |
| 138 void TelnetServer::StateMachineStep(unsigned char c) { | 159 void TelnetServer::StateMachineStep(unsigned char c) { |
| 139 switch (input_state_) { | 160 switch (input_state_) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 // Ignore ESC sequence content for now. | 240 // Ignore ESC sequence content for now. |
| 220 } else { | 241 } else { |
| 221 // Final character in ESC sequence. | 242 // Final character in ESC sequence. |
| 222 input_state_ = NOT_IN_IAC_OR_ESC_SEQUENCE; | 243 input_state_ = NOT_IN_IAC_OR_ESC_SEQUENCE; |
| 223 } | 244 } |
| 224 break; | 245 break; |
| 225 } | 246 } |
| 226 } | 247 } |
| 227 | 248 |
| 228 void TelnetServer::Read() { | 249 void TelnetServer::Read() { |
| 229 char buf[READ_BUF_SIZE]; | 250 char buf[kReadBufSize + 1]; |
| 230 int len; | 251 int len; |
| 231 do { | 252 do { |
| 232 len = recv(socket_, buf, READ_BUF_SIZE, 0); | 253 len = recv(socket_, buf, kReadBufSize, 0); |
| 254 |
| 255 #if defined(OS_WIN) |
| 233 if (len == SOCKET_ERROR) { | 256 if (len == SOCKET_ERROR) { |
| 234 int err = WSAGetLastError(); | 257 int err = WSAGetLastError(); |
| 235 if (err == WSAEWOULDBLOCK) { | 258 if (err == WSAEWOULDBLOCK) |
| 236 break; | 259 break; |
| 237 } else { | 260 #else |
| 238 // TODO - error | 261 if (len == SOCKET_ERROR) { |
| 262 if (errno == EWOULDBLOCK || errno == EAGAIN) |
| 239 break; | 263 break; |
| 240 } | 264 #endif |
| 265 } else if (len == 0) { |
| 266 socket_delegate_->DidClose(this); |
| 241 } else { | 267 } else { |
| 242 const char *data = buf; | 268 const char *data = buf; |
| 243 for (int i = 0; i < len; ++i) { | 269 for (int i = 0; i < len; ++i) { |
| 244 unsigned char c = static_cast<unsigned char>(*data); | 270 unsigned char c = static_cast<unsigned char>(*data); |
| 245 StateMachineStep(c); | 271 StateMachineStep(c); |
| 246 data++; | 272 data++; |
| 247 } | 273 } |
| 248 } | 274 } |
| 249 } while (len == READ_BUF_SIZE); | 275 } while (len == kReadBufSize); |
| 250 } | 276 } |
| 251 | |
| OLD | NEW |