172 CHECK_NULL(socketExceptionCls);
173 }
174 fdObj = (*env)->GetObjectField(env, this, psi_fdID);
175
176 if (fdObj == NULL) {
177 (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
178 return;
179 }
180
181 if ((fd = socket(domain, type, 0)) == -1) {
182 /* note: if you run out of fds, you may not be able to load
183 * the exception class, and get a NoClassDefFoundError
184 * instead.
185 */
186 NET_ThrowNew(env, errno, "can't create socket");
187 return;
188 }
189
190 /* Disable IPV6_V6ONLY to ensure dual-socket support */
191 if (domain == AF_INET6) {
192 int arg = 0;
193 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
194 sizeof(int)) < 0) {
195 NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
196 close(fd);
197 return;
198 }
199 }
200
201 /*
202 * If this is a server socket then enable SO_REUSEADDR
203 * automatically and set to non blocking.
204 */
205 ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
206 if (ssObj != NULL) {
207 int arg = 1;
208 SET_NONBLOCKING(fd);
209 if (NET_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
210 sizeof(arg)) < 0) {
211 NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
212 close(fd);
|
172 CHECK_NULL(socketExceptionCls);
173 }
174 fdObj = (*env)->GetObjectField(env, this, psi_fdID);
175
176 if (fdObj == NULL) {
177 (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
178 return;
179 }
180
181 if ((fd = socket(domain, type, 0)) == -1) {
182 /* note: if you run out of fds, you may not be able to load
183 * the exception class, and get a NoClassDefFoundError
184 * instead.
185 */
186 NET_ThrowNew(env, errno, "can't create socket");
187 return;
188 }
189
190 /* Disable IPV6_V6ONLY to ensure dual-socket support */
191 if (domain == AF_INET6) {
192 int arg = 1; // ENABLE
193 if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
194 sizeof(int)) < 0) {
195 NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
196 close(fd);
197 return;
198 }
199 }
200
201 /*
202 * If this is a server socket then enable SO_REUSEADDR
203 * automatically and set to non blocking.
204 */
205 ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
206 if (ssObj != NULL) {
207 int arg = 1;
208 SET_NONBLOCKING(fd);
209 if (NET_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
210 sizeof(arg)) < 0) {
211 NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
212 close(fd);
|