Skip to content

Commit 1e702fe

Browse files
committed
classlib: implement java.net.Socket
This patch introduces the implementation of the java.net.Socket class, providing functionality for creating, connecting, and managing sockets in a WASI-based environment. Additionally, it includes the implementation of several related networking classes: - java.net.ServerSocket - java.net.InetAddress - java.net.Inet4Address - java.net.Inet6Address - java.net.SocketAddress - java.net.InetSocketAddress - java.net.Proxy - java.net.NetworkInterface - java.net.SocketException - java.net.UnknownHostException
1 parent ebd8caa commit 1e702fe

File tree

13 files changed

+1577
-0
lines changed

13 files changed

+1577
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2025 Maksim Tiushev.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.teavm.classlib.java.net;
17+
18+
public final class TInet4Address extends TInetAddress {
19+
static final int INADDRSZ = 4;
20+
21+
TInet4Address(byte[] addr, String hostname) {
22+
super(addr, hostname, IPv4);
23+
validateIPv4Address(addr);
24+
}
25+
26+
private static void validateIPv4Address(byte[] addr) {
27+
if (addr.length != INADDRSZ) {
28+
throw new IllegalArgumentException("IPv4 address must be exactly 4 bytes long.");
29+
}
30+
}
31+
32+
@Override
33+
public boolean isAnyLocalAddress() {
34+
return address[0] == 0 && address[1] == 0 && address[2] == 0 && address[3] == 0;
35+
}
36+
37+
@Override
38+
public boolean isLoopbackAddress() {
39+
return address[0] == 127;
40+
}
41+
42+
@Override
43+
public boolean isLinkLocalAddress() {
44+
return (address[0] & 0xFF) == 169 && (address[1] & 0xFF) == 254;
45+
}
46+
47+
@Override
48+
public boolean isMCGlobal() {
49+
return (address[0] & 0xFF) >= 224
50+
&& (address[0] & 0xFF) <= 238
51+
&& !(address[0] == 224 && address[1] == 0 && address[2] == 0);
52+
}
53+
54+
@Override
55+
public boolean isMCLinkLocal() {
56+
return (address[0] & 0xFF) == 224 && (address[1] & 0xFF) == 0;
57+
}
58+
59+
@Override
60+
public boolean isMCOrgLocal() {
61+
return (address[0] & 0xFF) == 239 && (address[1] & 0xFF) >= 192;
62+
}
63+
64+
@Override
65+
public boolean isMCSiteLocal() {
66+
return (address[0] & 0xFF) == 239 && (address[1] & 0xFF) == 255;
67+
}
68+
69+
@Override
70+
public boolean isMulticastAddress() {
71+
return (address[0] & 0xFF) >= 224 && (address[0] & 0xFF) <= 239;
72+
}
73+
74+
@Override
75+
public boolean isSiteLocalAddress() {
76+
int firstOctet = address[0] & 0xFF;
77+
int secondOctet = address[1] & 0xFF;
78+
79+
return (firstOctet == 10)
80+
|| (firstOctet == 172 && secondOctet >= 16 && secondOctet <= 31)
81+
|| (firstOctet == 192 && secondOctet == 168);
82+
}
83+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* Copyright 2025 Maksim Tiushev.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.teavm.classlib.java.net;
17+
18+
public final class TInet6Address extends TInetAddress {
19+
static final int INADDRSZ = 16;
20+
21+
TInet6Address(byte[] addr, String hostname) {
22+
super(addr, hostname, IPv6);
23+
validateIPv6Address(addr);
24+
}
25+
26+
private static void validateIPv6Address(byte[] addr) {
27+
if (addr.length != INADDRSZ) {
28+
throw new IllegalArgumentException("IPv6 address must be exactly 16 bytes long.");
29+
}
30+
}
31+
32+
@Override
33+
public String getHostAddress() {
34+
StringBuilder sb = new StringBuilder();
35+
int[] segments = new int[8];
36+
37+
for (int i = 0; i < 8; i++) {
38+
segments[i] = ((address[i * 2] & 0xFF) << 8) | (address[i * 2 + 1] & 0xFF);
39+
}
40+
41+
int startZero = -1;
42+
int maxZeroLength = 0;
43+
int zeroLength = 0;
44+
int currentStart = -1;
45+
for (int i = 0; i < segments.length; i++) {
46+
if (segments[i] == 0) {
47+
if (currentStart == -1) {
48+
currentStart = i;
49+
}
50+
zeroLength++;
51+
} else {
52+
if (zeroLength > maxZeroLength) {
53+
maxZeroLength = zeroLength;
54+
startZero = currentStart;
55+
}
56+
zeroLength = 0;
57+
currentStart = -1;
58+
}
59+
}
60+
if (zeroLength > maxZeroLength) {
61+
maxZeroLength = zeroLength;
62+
startZero = currentStart;
63+
}
64+
65+
for (int i = 0; i < segments.length; i++) {
66+
if (startZero == i && maxZeroLength > 1) {
67+
if (i == 0) {
68+
sb.append("::");
69+
} else {
70+
sb.append(':');
71+
}
72+
i += maxZeroLength - 1;
73+
continue;
74+
}
75+
sb.append(Integer.toHexString(segments[i]));
76+
if (i < segments.length - 1) {
77+
sb.append(':');
78+
}
79+
}
80+
return sb.toString();
81+
}
82+
83+
@Override
84+
public boolean isAnyLocalAddress() {
85+
for (byte b : address) {
86+
if (b != 0) {
87+
return false;
88+
}
89+
}
90+
return true;
91+
}
92+
93+
public boolean isIPv4CompatibleAddress() {
94+
for (int i = 0; i < 12; i++) {
95+
if (address[i] != 0) {
96+
return false;
97+
}
98+
}
99+
return true;
100+
}
101+
102+
@Override
103+
public boolean isLinkLocalAddress() {
104+
return (address[0] & 0xFF) == 0xFE && (address[1] & 0xC0) == 0x80;
105+
}
106+
107+
@Override
108+
public boolean isLoopbackAddress() {
109+
if (address[15] != 1) {
110+
return false;
111+
}
112+
for (int i = 0; i < 15; i++) {
113+
if (address[i] != 0) {
114+
return false;
115+
}
116+
}
117+
return true;
118+
}
119+
120+
@Override
121+
public boolean isMCGlobal() {
122+
return (address[0] & 0xFF) == 0xFF && (address[1] & 0x0F) == 0x0E;
123+
}
124+
125+
@Override
126+
public boolean isMCLinkLocal() {
127+
return (address[0] & 0xFF) == 0xFF && (address[1] & 0x0F) == 0x02;
128+
}
129+
130+
@Override
131+
public boolean isMCNodeLocal() {
132+
return (address[0] & 0xFF) == 0xFF && (address[1] & 0x0F) == 0x01;
133+
}
134+
135+
@Override
136+
public boolean isMCOrgLocal() {
137+
return (address[0] & 0xFF) == 0xFF && (address[1] & 0x0F) == 0x08;
138+
}
139+
140+
@Override
141+
public boolean isMCSiteLocal() {
142+
return (address[0] & 0xFF) == 0xFF && (address[1] & 0x0F) == 0x05;
143+
}
144+
145+
@Override
146+
public boolean isMulticastAddress() {
147+
return (address[0] & 0xFF) == 0xFF;
148+
}
149+
150+
@Override
151+
public boolean isSiteLocalAddress() {
152+
return (address[0] & 0xFF) == 0xFE && (address[1] & 0xC0) == 0xC0;
153+
}
154+
}

0 commit comments

Comments
 (0)