Skip to content

Commit c819abc

Browse files
committed
Start on net2
1 parent f219938 commit c819abc

4 files changed

Lines changed: 194 additions & 0 deletions

File tree

src/node.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <node_buffer.h>
1414
#include <node_io_watcher.h>
15+
#include <node_net2.h>
1516
#include <node_events.h>
1617
#include <node_dns.h>
1718
#include <node_net.h>
@@ -856,6 +857,8 @@ static Local<Object> Load(int argc, char *argv[]) {
856857
Stat::Initialize(process); // stat.cc
857858
SignalHandler::Initialize(process); // signal_handler.cc
858859

860+
InitNet2(process); // net2.cc
861+
859862
Stdio::Initialize(process); // stdio.cc
860863
ChildProcess::Initialize(process); // child_process.cc
861864
DefineConstants(process); // constants.cc

src/node_net2.cc

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include <node_net2.h>
2+
#include <v8.h>
3+
4+
#include <node.h>
5+
6+
#include <string.h>
7+
8+
#include <sys/types.h>
9+
#include <sys/socket.h>
10+
#include <sys/un.h>
11+
#include <unistd.h>
12+
#include <fcntl.h>
13+
#include <arpa/inet.h> /* inet_pton */
14+
15+
#include <errno.h>
16+
17+
18+
19+
namespace node {
20+
21+
using namespace v8;
22+
23+
static Persistent<String> errno_symbol;
24+
static Persistent<String> syscall_symbol;
25+
26+
static inline Local<Value> ErrnoException(int errorno, const char *syscall, const char *msg = "") {
27+
if (!msg[0]) msg = strerror(errorno);
28+
Local<Value> e = Exception::Error(String::NewSymbol(msg));
29+
Local<Object> obj = e->ToObject();
30+
obj->Set(errno_symbol, Integer::New(errorno));
31+
obj->Set(syscall_symbol, String::NewSymbol(syscall));
32+
return e;
33+
}
34+
35+
// Creates a new non-blocking socket fd
36+
// t.socket("TCP");
37+
// t.socket("UNIX");
38+
// t.socket("UDP");
39+
static Handle<Value> Socket(const Arguments& args) {
40+
HandleScope scope;
41+
42+
// default to TCP
43+
int domain = PF_INET6;
44+
int type = SOCK_STREAM;
45+
46+
if (args[0]->IsString()) {
47+
String::Utf8Value t(args[0]->ToString());
48+
if (0 == strcasecmp(*t, "TCP")) {
49+
domain = PF_INET6;
50+
type = SOCK_STREAM;
51+
} else if (0 == strcasecmp(*t, "UDP")) {
52+
domain = PF_INET6;
53+
type = SOCK_DGRAM;
54+
} else if (0 == strcasecmp(*t, "UNIX")) {
55+
domain = PF_UNIX;
56+
type = SOCK_STREAM;
57+
} else {
58+
return ThrowException(Exception::Error(
59+
String::New("Unknown socket type.")));
60+
}
61+
}
62+
63+
int fd = socket(domain, type, 0);
64+
65+
if (fd < 0) return ThrowException(ErrnoException(errno, "socket"));
66+
67+
int fcntl_errno;
68+
69+
int flags = fcntl(fd, F_GETFL, 0);
70+
if (flags == -1) {
71+
fcntl_errno = errno;
72+
close(fd);
73+
return ThrowException(ErrnoException(fcntl_errno, "fcntl"));
74+
}
75+
76+
flags |= O_NONBLOCK;
77+
78+
if (fcntl(fd, F_SETFL, flags) == -1) {
79+
fcntl_errno = errno;
80+
close(fd);
81+
return ThrowException(ErrnoException(fcntl_errno, "fcntl"));
82+
}
83+
84+
return scope.Close(Integer::New(fd));
85+
}
86+
87+
// 2 arguments means connect with unix
88+
// t.connect(fd, "/tmp/socket")
89+
//
90+
// 3 arguments means connect with TCP or UDP
91+
// t.connect(fd, "127.0.0.1", 80)
92+
static Handle<Value> Connect(const Arguments& args) {
93+
HandleScope scope;
94+
95+
if (!args[0]->IsInt32()) {
96+
return ThrowException(Exception::TypeError(
97+
String::New("First argument should be file descriptor")));
98+
}
99+
100+
if (args.Length() < 2) {
101+
return ThrowException(Exception::TypeError(
102+
String::New("Must have at least two args")));
103+
}
104+
105+
int fd = args[0]->Int32Value();
106+
107+
struct sockaddr *addr;
108+
socklen_t addrlen;
109+
110+
if (args.Length() == 2) {
111+
// UNIX
112+
String::Utf8Value path(args[1]->ToString());
113+
114+
struct sockaddr_un un = {0};
115+
116+
if (path.length() > sizeof un.sun_path) {
117+
return ThrowException(Exception::Error(String::New("Socket path too long")));
118+
}
119+
120+
un.sun_family = AF_UNIX;
121+
strcpy(un.sun_path, *path);
122+
123+
addr = (struct sockaddr*)&un;
124+
addrlen = path.length() + sizeof(un.sun_family);
125+
126+
} else {
127+
// TCP or UDP
128+
String::Utf8Value ip(args[1]->ToString());
129+
int port = args[2]->Int32Value();
130+
131+
struct sockaddr_in6 in6 = {0};
132+
133+
char ipv6[255] = "::FFFF:";
134+
135+
if (inet_pton(AF_INET, *ip, &(in6.sin6_addr)) > 0) {
136+
// If this is an IPv4 address then we need to change it to the
137+
// IPv4-mapped-on-IPv6 format which looks like
138+
// ::FFFF:<IPv4 address>
139+
// For more information see "Address Format" ipv6(7) and "BUGS" in
140+
// inet_pton(3)
141+
strcat(ipv6, *ip);
142+
} else {
143+
strcpy(ipv6, *ip);
144+
}
145+
146+
if (inet_pton(AF_INET6, ipv6, &(in6.sin6_addr)) <= 0) {
147+
return ThrowException(
148+
ErrnoException(errno, "inet_pton", "Invalid IP Address"));
149+
}
150+
151+
in6.sin6_family = AF_INET6;
152+
in6.sin6_port = htons(port);
153+
154+
addr = (struct sockaddr*)&in6;
155+
addrlen = sizeof in6;
156+
}
157+
158+
int r = connect(fd, addr, addrlen);
159+
160+
if (r < 0 && errno != EINPROGRESS) {
161+
return ThrowException(ErrnoException(errno, "connect"));
162+
}
163+
164+
return Undefined();
165+
}
166+
167+
168+
void InitNet2(Handle<Object> target) {
169+
HandleScope scope;
170+
171+
NODE_SET_METHOD(target, "socket", Socket);
172+
NODE_SET_METHOD(target, "connect", Connect);
173+
174+
errno_symbol = NODE_PSYMBOL("errno");
175+
syscall_symbol = NODE_PSYMBOL("syscall");
176+
}
177+
178+
} // namespace node

src/node_net2.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef NODE_NET2
2+
#define NODE_NET2
3+
4+
#include <v8.h>
5+
6+
namespace node {
7+
8+
void InitNet2(v8::Handle<v8::Object> target);
9+
10+
}
11+
12+
#endif // NODE_NET2

wscript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ def build(bld):
323323
node.source = """
324324
src/node.cc
325325
src/node_buffer.cc
326+
src/node_net2.cc
326327
src/node_io_watcher.cc
327328
src/node_child_process.cc
328329
src/node_constants.cc

0 commit comments

Comments
 (0)