19
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
23
#include <node_buffer.h>
25
#include <handle_wrap.h>
26
#include <stream_wrap.h>
23
#include "node_buffer.h"
25
#include "handle_wrap.h"
26
#include "stream_wrap.h"
29
29
#include <stdlib.h>
31
// Temporary hack: libuv should provide uv_inet_pton and uv_inet_ntop.
32
#if defined(__MINGW32__) || defined(_MSC_VER)
34
# include <inet_net_pton.h>
35
# include <inet_ntop.h>
37
# define uv_inet_pton ares_inet_pton
38
# define uv_inet_ntop ares_inet_ntop
41
# include <arpa/inet.h>
42
# define uv_inet_pton inet_pton
43
# define uv_inet_ntop inet_ntop
47
assert(!args.Holder().IsEmpty()); \
48
assert(args.Holder()->InternalFieldCount() > 0); \
50
static_cast<TCPWrap*>(args.Holder()->GetPointerFromInternalField(0)); \
53
err.code = UV_EBADF; \
55
return scope.Close(Integer::New(-1)); \
37
using v8::FunctionTemplate;
39
using v8::HandleScope;
63
44
using v8::Persistent;
65
using v8::HandleScope;
66
using v8::FunctionTemplate;
45
using v8::PropertyAttribute;
69
47
using v8::TryCatch;
73
48
using v8::Undefined;
75
51
static Persistent<Function> tcpConstructor;
76
static Persistent<String> family_symbol;
77
static Persistent<String> address_symbol;
78
static Persistent<String> port_symbol;
52
static Persistent<String> oncomplete_sym;
53
static Persistent<String> onconnection_sym;
81
56
typedef class ReqWrap<uv_connect_t> ConnectWrap;
58
Local<Object> AddressToJS(const sockaddr* addr);
84
61
Local<Object> TCPWrap::Instantiate() {
85
62
// If this assert fire then process.binding('tcp_wrap') hasn't been
105
82
t->InstanceTemplate()->SetInternalFieldCount(1);
84
enum PropertyAttribute attributes =
85
static_cast<PropertyAttribute>(v8::ReadOnly | v8::DontDelete);
86
t->InstanceTemplate()->SetAccessor(String::New("fd"),
107
93
NODE_SET_PROTOTYPE_METHOD(t, "close", HandleWrap::Close);
95
NODE_SET_PROTOTYPE_METHOD(t, "ref", HandleWrap::Ref);
96
NODE_SET_PROTOTYPE_METHOD(t, "unref", HandleWrap::Unref);
109
98
NODE_SET_PROTOTYPE_METHOD(t, "readStart", StreamWrap::ReadStart);
110
99
NODE_SET_PROTOTYPE_METHOD(t, "readStop", StreamWrap::ReadStop);
111
NODE_SET_PROTOTYPE_METHOD(t, "write", StreamWrap::Write);
112
100
NODE_SET_PROTOTYPE_METHOD(t, "shutdown", StreamWrap::Shutdown);
102
NODE_SET_PROTOTYPE_METHOD(t, "writeBuffer", StreamWrap::WriteBuffer);
103
NODE_SET_PROTOTYPE_METHOD(t, "writeAsciiString", StreamWrap::WriteAsciiString);
104
NODE_SET_PROTOTYPE_METHOD(t, "writeUtf8String", StreamWrap::WriteUtf8String);
105
NODE_SET_PROTOTYPE_METHOD(t, "writeUcs2String", StreamWrap::WriteUcs2String);
107
NODE_SET_PROTOTYPE_METHOD(t, "open", Open);
114
108
NODE_SET_PROTOTYPE_METHOD(t, "bind", Bind);
115
109
NODE_SET_PROTOTYPE_METHOD(t, "listen", Listen);
116
110
NODE_SET_PROTOTYPE_METHOD(t, "connect", Connect);
128
122
tcpConstructor = Persistent<Function>::New(t->GetFunction());
130
family_symbol = NODE_PSYMBOL("family");
131
address_symbol = NODE_PSYMBOL("address");
132
port_symbol = NODE_PSYMBOL("port");
124
onconnection_sym = NODE_PSYMBOL("onconnection");
125
oncomplete_sym = NODE_PSYMBOL("oncomplete");
134
127
target->Set(String::NewSymbol("TCP"), tcpConstructor);
131
TCPWrap* TCPWrap::Unwrap(Local<Object> obj) {
132
assert(!obj.IsEmpty());
133
assert(obj->InternalFieldCount() > 0);
134
return static_cast<TCPWrap*>(obj->GetPointerFromInternalField(0));
138
uv_tcp_t* TCPWrap::UVHandle() {
138
143
Handle<Value> TCPWrap::New(const Arguments& args) {
139
144
// This constructor should not be exposed to public javascript.
140
145
// Therefore we assert that we are not trying to call this as a
166
171
Handle<Value> TCPWrap::GetSockName(const Arguments& args) {
167
172
HandleScope scope;
168
173
struct sockaddr_storage address;
171
char ip[INET6_ADDRSTRLEN];
175
177
int addrlen = sizeof(address);
176
178
int r = uv_tcp_getsockname(&wrap->handle_,
177
179
reinterpret_cast<sockaddr*>(&address),
180
Local<Object> sockname = Object::New();
182
183
SetErrno(uv_last_error(uv_default_loop()));
184
family = address.ss_family;
186
if (family == AF_INET) {
187
struct sockaddr_in* addrin = (struct sockaddr_in*)&address;
188
uv_inet_ntop(AF_INET, &(addrin->sin_addr), ip, INET6_ADDRSTRLEN);
189
port = ntohs(addrin->sin_port);
190
} else if (family == AF_INET6) {
191
struct sockaddr_in6* addrin6 = (struct sockaddr_in6*)&address;
192
uv_inet_ntop(AF_INET6, &(addrin6->sin6_addr), ip, INET6_ADDRSTRLEN);
193
port = ntohs(addrin6->sin6_port);
195
assert(0 && "bad address family");
199
sockname->Set(port_symbol, Integer::New(port));
200
sockname->Set(family_symbol, Integer::New(family));
201
sockname->Set(address_symbol, String::New(ip));
204
return scope.Close(sockname);
187
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
188
return scope.Close(AddressToJS(addr));
208
192
Handle<Value> TCPWrap::GetPeerName(const Arguments& args) {
209
193
HandleScope scope;
210
194
struct sockaddr_storage address;
213
char ip[INET6_ADDRSTRLEN];
217
198
int addrlen = sizeof(address);
218
199
int r = uv_tcp_getpeername(&wrap->handle_,
219
200
reinterpret_cast<sockaddr*>(&address),
222
Local<Object> sockname = Object::New();
224
204
SetErrno(uv_last_error(uv_default_loop()));
226
family = address.ss_family;
228
if (family == AF_INET) {
229
struct sockaddr_in* addrin = (struct sockaddr_in*)&address;
230
uv_inet_ntop(AF_INET, &(addrin->sin_addr), ip, INET6_ADDRSTRLEN);
231
port = ntohs(addrin->sin_port);
232
} else if (family == AF_INET6) {
233
struct sockaddr_in6* addrin6 = (struct sockaddr_in6*)&address;
234
uv_inet_ntop(AF_INET6, &(addrin6->sin6_addr), ip, INET6_ADDRSTRLEN);
235
port = ntohs(addrin6->sin6_port);
237
assert(0 && "bad address family");
241
sockname->Set(port_symbol, Integer::New(port));
242
sockname->Set(family_symbol, Integer::New(family));
243
sockname->Set(address_symbol, String::New(ip));
246
return scope.Close(sockname);
208
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
209
return scope.Close(AddressToJS(addr));
250
213
Handle<Value> TCPWrap::SetNoDelay(const Arguments& args) {
251
214
HandleScope scope;
255
int r = uv_tcp_nodelay(&wrap->handle_, 1);
218
int enable = static_cast<int>(args[0]->BooleanValue());
219
int r = uv_tcp_nodelay(&wrap->handle_, enable);
257
221
SetErrno(uv_last_error(uv_default_loop()));
440
// also used by udp_wrap.cc
441
Local<Object> AddressToJS(const sockaddr* addr) {
442
static Persistent<String> address_sym;
443
static Persistent<String> family_sym;
444
static Persistent<String> port_sym;
445
static Persistent<String> ipv4_sym;
446
static Persistent<String> ipv6_sym;
449
char ip[INET6_ADDRSTRLEN];
450
const sockaddr_in *a4;
451
const sockaddr_in6 *a6;
454
if (address_sym.IsEmpty()) {
455
address_sym = NODE_PSYMBOL("address");
456
family_sym = NODE_PSYMBOL("family");
457
port_sym = NODE_PSYMBOL("port");
458
ipv4_sym = NODE_PSYMBOL("IPv4");
459
ipv6_sym = NODE_PSYMBOL("IPv6");
462
Local<Object> info = Object::New();
464
switch (addr->sa_family) {
466
a6 = reinterpret_cast<const sockaddr_in6*>(addr);
467
uv_inet_ntop(AF_INET6, &a6->sin6_addr, ip, sizeof ip);
468
port = ntohs(a6->sin6_port);
469
info->Set(address_sym, String::New(ip));
470
info->Set(family_sym, ipv6_sym);
471
info->Set(port_sym, Integer::New(port));
475
a4 = reinterpret_cast<const sockaddr_in*>(addr);
476
uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip);
477
port = ntohs(a4->sin_port);
478
info->Set(address_sym, String::New(ip));
479
info->Set(family_sym, ipv4_sym);
480
info->Set(port_sym, Integer::New(port));
484
info->Set(address_sym, String::Empty());
487
return scope.Close(info);
467
491
} // namespace node
469
493
NODE_MODULE(node_tcp_wrap, node::TCPWrap::Initialize)