125 |
|
|
126 |
/* Get the buffer from the packet */ |
/* Get the buffer from the packet */ |
127 |
cls = (*env)->GetObjectClass(env, packet); |
cls = (*env)->GetObjectClass(env, packet); |
128 |
|
if (cls == NULL) |
129 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
130 |
|
|
131 |
mid = (*env)->GetMethodID(env, cls, "getData", "()[B"); |
mid = (*env)->GetMethodID(env, cls, "getData", "()[B"); |
132 |
if (!mid) |
if (mid == NULL) |
133 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
134 |
|
|
135 |
arr = (*env)->CallObjectMethod(env, packet, mid); |
arr = (*env)->CallObjectMethod(env, packet, mid); |
136 |
if (!arr) |
if ((arr == NULL) || (*env)->ExceptionOccurred(env)) |
137 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
138 |
|
|
139 |
/* Now get the length from the packet */ |
/* Now get the length from the packet */ |
140 |
mid = (*env)->GetMethodID(env, cls, "getLength", "()I"); |
mid = (*env)->GetMethodID(env, cls, "getLength", "()I"); |
141 |
if (!mid) |
if (mid == NULL) |
142 |
{ |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
143 |
(*env)->ReleaseByteArrayElements(env, arr, buf, 0); |
|
|
JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); |
|
|
return; |
|
|
} |
|
144 |
len = (*env)->CallIntMethod(env, packet, mid); |
len = (*env)->CallIntMethod(env, packet, mid); |
145 |
DBG("Got the length\n"); |
if ((*env)->ExceptionOccurred(env)) |
146 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
147 |
|
|
148 |
|
DBG("PlainDatagramSocketImpl.receive(): Got the length\n"); |
149 |
|
|
150 |
/* Receive the packet */ |
/* Receive the packet */ |
151 |
/* should we try some sort of validation on the length? */ |
/* should we try some sort of validation on the length? */ |
152 |
bytes_read = _javanet_recvfrom(env, this, arr, 0, len, &addr, &port); |
bytes_read = _javanet_recvfrom(env, this, arr, 0, len, &addr, &port); |
153 |
if (bytes_read == -1) |
if ((bytes_read == -1) || (*env)->ExceptionOccurred(env)) |
154 |
{ |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
155 |
/* Taking a chance here because there is a pending exception */ |
|
156 |
(*env)->ReleaseByteArrayElements(env, arr, buf, 0); |
DBG("PlainDatagramSocketImpl.receive(): Received packet\n"); |
|
return; |
|
|
} |
|
|
DBG("Received packet\n"); |
|
157 |
|
|
158 |
/* Store the address */ |
/* Store the address */ |
159 |
addr = ntohl(addr); |
addr = ntohl(addr); |
161 |
(addr & 0x00FF0000) >> 16, (addr & 0x0000FF00) >> 8, |
(addr & 0x00FF0000) >> 16, (addr & 0x0000FF00) >> 8, |
162 |
(addr & 0x000000FF)); |
(addr & 0x000000FF)); |
163 |
ip_str_obj = (*env)->NewStringUTF(env, ip_str); |
ip_str_obj = (*env)->NewStringUTF(env, ip_str); |
164 |
|
if (ip_str_obj == NULL) |
165 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
166 |
|
|
167 |
addr_cls = (*env)->FindClass(env, "java/net/InetAddress"); |
addr_cls = (*env)->FindClass(env, "java/net/InetAddress"); |
168 |
if (!addr_cls) |
if (addr_cls == NULL) |
169 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
170 |
DBG("Found InetAddress class\n"); |
DBG("PlainDatagramSocketImpl.receive(): Found InetAddress class\n"); |
171 |
|
|
172 |
mid = (*env)->GetStaticMethodID(env, addr_cls, "getByName", |
mid = (*env)->GetStaticMethodID(env, addr_cls, "getByName", |
173 |
"(Ljava/lang/String;)Ljava/net/InetAddress;"); |
"(Ljava/lang/String;)Ljava/net/InetAddress;"); |
174 |
if (!mid) |
if (mid == NULL) |
175 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
176 |
DBG("Found InetAddress.getByName method\n"); |
DBG("PlainDatagramSocketImpl.receive(): Found InetAddress.getByName method\n"); |
177 |
|
|
178 |
addr_obj = (*env)->CallStaticObjectMethod(env, addr_cls, mid, ip_str_obj); |
addr_obj = (*env)->CallStaticObjectMethod(env, addr_cls, mid, ip_str_obj); |
179 |
|
if ((*env)->ExceptionOccurred(env)) |
180 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
181 |
|
|
182 |
mid = (*env)->GetMethodID(env, cls, "setAddress", |
mid = (*env)->GetMethodID(env, cls, "setAddress", |
183 |
"(Ljava/net/InetAddress;)V"); |
"(Ljava/net/InetAddress;)V"); |
184 |
if (!mid) |
if (mid == NULL) |
185 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
186 |
|
|
187 |
(*env)->CallVoidMethod(env, packet, mid, addr_obj); |
(*env)->CallVoidMethod(env, packet, mid, addr_obj); |
188 |
DBG("Stored the address\n"); |
if ((*env)->ExceptionOccurred(env)) |
189 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
190 |
|
|
191 |
|
DBG("PlainDatagramSocketImpl.receive(): Stored the address\n"); |
192 |
|
|
193 |
/* Store the port */ |
/* Store the port */ |
194 |
port = ntohs(((unsigned short)port)); |
port = ntohs(((unsigned short)port)); |
195 |
|
|
196 |
mid = (*env)->GetMethodID(env, cls, "setPort", "(I)V"); |
mid = (*env)->GetMethodID(env, cls, "setPort", "(I)V"); |
197 |
if (!mid) |
if (mid == NULL) |
198 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
199 |
|
|
200 |
(*env)->CallVoidMethod(env, packet, mid, port); |
(*env)->CallVoidMethod(env, packet, mid, port); |
201 |
DBG("Stored the port\n"); |
if ((*env)->ExceptionOccurred(env)) |
202 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
203 |
|
|
204 |
|
DBG("PlainDatagramSocketImpl.receive(): Stored the port\n"); |
205 |
|
|
206 |
/* Store back the length */ |
/* Store back the length */ |
207 |
mid = (*env)->GetMethodID(env, cls, "setLength", "(I)V"); |
mid = (*env)->GetMethodID(env, cls, "setLength", "(I)V"); |
208 |
if (!mid) |
if (mid == NULL) |
209 |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal Error"); return; } |
210 |
|
|
211 |
(*env)->CallVoidMethod(env, packet, mid, bytes_read); |
(*env)->CallVoidMethod(env, packet, mid, bytes_read); |
212 |
DBG("Stored the length\n"); |
if ((*env)->ExceptionOccurred(env)) |
213 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
214 |
|
|
215 |
|
DBG("PlainDatagramSocketImpl.receive(): Stored the length\n"); |
216 |
|
|
217 |
return; |
return; |
218 |
} |
} |
227 |
jobject addr, jint port, jarray buf, |
jobject addr, jint port, jarray buf, |
228 |
jint len) |
jint len) |
229 |
{ |
{ |
230 |
_javanet_sendto(env, this, buf, 0, len, _javanet_get_netaddr(env, addr), |
struct ip_mreq ipm; |
231 |
|
memset(&ipm, 0, sizeof(ipm)); |
232 |
|
ipm.imr_multiaddr.s_addr = _javanet_get_netaddr(env, addr); |
233 |
|
|
234 |
|
if ((*env)->ExceptionOccurred(env)) |
235 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
236 |
|
|
237 |
|
DBG("PlainDatagramSocketImpl.sendto(): have addr\n"); |
238 |
|
|
239 |
|
_javanet_sendto(env, this, buf, 0, len, ipm.imr_multiaddr.s_addr, |
240 |
htons(((unsigned short)port))); |
htons(((unsigned short)port))); |
241 |
|
|
242 |
|
if ((*env)->ExceptionOccurred(env)) |
243 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
244 |
|
|
245 |
|
DBG("PlainDatagramSocketImpl.sendto(): finished\n"); |
246 |
} |
} |
247 |
|
|
248 |
/*************************************************************************/ |
/*************************************************************************/ |
254 |
Java_java_net_PlainDatagramSocketImpl_join(JNIEnv *env, jobject this, |
Java_java_net_PlainDatagramSocketImpl_join(JNIEnv *env, jobject this, |
255 |
jobject addr) |
jobject addr) |
256 |
{ |
{ |
257 |
int rc; |
int rc, fd; |
258 |
struct ip_mreq ipm; |
struct ip_mreq ipm; |
259 |
|
|
260 |
memset(&ipm, 0, sizeof(ipm)); |
memset(&ipm, 0, sizeof(ipm)); |
261 |
ipm.imr_multiaddr.s_addr = _javanet_get_netaddr(env, addr); |
ipm.imr_multiaddr.s_addr = _javanet_get_netaddr(env, addr); |
262 |
|
if ((*env)->ExceptionOccurred(env)) |
263 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
264 |
|
|
265 |
ipm.imr_interface.s_addr = INADDR_ANY; |
ipm.imr_interface.s_addr = INADDR_ANY; |
266 |
|
|
267 |
rc = setsockopt(_javanet_get_int_field(env, this, "native_fd"), |
fd = _javanet_get_int_field(env, this, "native_fd"); |
268 |
IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipm, sizeof(ipm)); |
if ((*env)->ExceptionOccurred(env)) |
269 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
270 |
|
|
271 |
|
DBG("PlainDatagramSocketImpl.join(): have native fd\n"); |
272 |
|
|
273 |
|
rc = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &ipm, sizeof(ipm)); |
274 |
|
|
275 |
if (rc == -1) |
if (rc == -1) |
276 |
JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); |
JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); |
277 |
|
|
278 |
|
DBG("PlainDatagramSocketImpl.join(): finished\n"); |
279 |
} |
} |
280 |
|
|
281 |
/*************************************************************************/ |
/*************************************************************************/ |
287 |
Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this, |
Java_java_net_PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this, |
288 |
jobject addr) |
jobject addr) |
289 |
{ |
{ |
290 |
int rc; |
int rc, fd; |
291 |
struct ip_mreq ipm; |
struct ip_mreq ipm; |
292 |
|
|
293 |
memset(&ipm, 0, sizeof(ipm)); |
memset(&ipm, 0, sizeof(ipm)); |
294 |
ipm.imr_multiaddr.s_addr = _javanet_get_netaddr(env, addr); |
ipm.imr_multiaddr.s_addr = _javanet_get_netaddr(env, addr); |
295 |
|
if ((*env)->ExceptionOccurred(env)) |
296 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
297 |
|
|
298 |
ipm.imr_interface.s_addr = INADDR_ANY; |
ipm.imr_interface.s_addr = INADDR_ANY; |
299 |
|
|
300 |
rc = setsockopt(_javanet_get_int_field(env, this, "native_fd"), |
fd = _javanet_get_int_field(env, this, "native_fd"); |
301 |
IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipm, sizeof(ipm)); |
if ((*env)->ExceptionOccurred(env)) |
302 |
|
{ JCL_ThrowException(env, IO_EXCEPTION, "Internal error"); return; } |
303 |
|
|
304 |
|
DBG("PlainDatagramSocketImpl.leave(): have native fd\n"); |
305 |
|
|
306 |
|
rc = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &ipm, sizeof(ipm)); |
307 |
|
|
308 |
if (rc == -1) |
if (rc == -1) |
309 |
JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); |
JCL_ThrowException(env, IO_EXCEPTION, strerror(errno)); |
|
} |
|
|
|
|
310 |
|
|
311 |
|
DBG("PlainDatagramSocketImpl.leave(): finished\n"); |
312 |
|
} |