1 /** 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * SPDX-License-Identifier: Apache-2.0. 4 */ 5 package software.amazon.awssdk.crt.io; 6 7 import software.amazon.awssdk.crt.CrtResource; 8 import software.amazon.awssdk.crt.CrtRuntimeException; 9 10 /** 11 * This class wraps the aws_socket_options from aws-c-io to provide 12 * access to TCP/UDP socket configuration in the AWS Common Runtime. 13 */ 14 public final class SocketOptions extends CrtResource { 15 16 /** 17 * Socket communications domain 18 */ 19 public enum SocketDomain { 20 /** 21 * Corresponds to PF_INET in Berkeley sockets 22 */ 23 IPv4(0), 24 /** 25 * Corresponds to PF_INET6 in Berkeley sockets 26 */ 27 IPv6(1), 28 /** 29 * Corresponds to PF_LOCAL in Berkeley sockets, usually UNIX domain sockets or named pipes 30 */ 31 LOCAL(2); 32 33 private int domain; 34 SocketDomain(int val)35 SocketDomain(int val) { 36 domain = val; 37 } 38 getValue()39 int getValue() { 40 return domain; 41 } 42 } 43 44 /** 45 * Socket type 46 */ 47 public enum SocketType { 48 /** 49 * Corresponds to SOCK_STREAM in Berkeley sockets (TCP) 50 */ 51 STREAM(0), 52 /** 53 * Corresponds to SOCK_DGRAM in Berkeley sockets (UDP) 54 */ 55 DGRAM(1); 56 57 private int type; 58 SocketType(int val)59 SocketType(int val) { 60 type = val; 61 } 62 getValue()63 int getValue() { 64 return type; 65 } 66 } 67 68 /** 69 * Sets the socket domain 70 */ 71 public SocketDomain domain = SocketDomain.IPv6; 72 /** 73 * Sets the socket type 74 */ 75 public SocketType type = SocketType.STREAM; 76 /** 77 * Sets the number of milliseconds before a connection will be considered timed out 78 */ 79 public int connectTimeoutMs = 3000; 80 /** 81 * Sets the number of seconds between TCP keepalive packets being sent to the peer 82 * 0 disables keepalive 83 */ 84 public int keepAliveIntervalSecs = 0; 85 /** 86 * Sets the number of seconds to wait for a keepalive response before considering the connection timed out 87 * 0 disables keepalive 88 */ 89 public int keepAliveTimeoutSecs = 0; 90 91 /** 92 * If true, enables periodic transmits of keepalive messages for detecting a disconnected peer. 93 */ 94 public boolean keepAlive = false; 95 96 /** 97 * Creates a new set of socket options 98 */ SocketOptions()99 public SocketOptions() { 100 101 } 102 103 @Override getNativeHandle()104 public long getNativeHandle() { 105 if (super.getNativeHandle() == 0) { 106 acquireNativeHandle(socketOptionsNew( 107 domain.getValue(), 108 type.getValue(), 109 connectTimeoutMs, 110 keepAliveIntervalSecs, 111 keepAliveTimeoutSecs, 112 keepAlive 113 )); 114 } 115 return super.getNativeHandle(); 116 } 117 118 /** 119 * Determines whether a resource releases its dependencies at the same time the native handle is released or if it waits. 120 * Resources that wait are responsible for calling releaseReferences() manually. 121 */ 122 @Override canReleaseReferencesImmediately()123 protected boolean canReleaseReferencesImmediately() { return true; } 124 125 /** 126 * Frees the native resources for this set of socket options 127 */ 128 @Override releaseNativeHandle()129 protected void releaseNativeHandle() { 130 if (!isNull()) { 131 socketOptionsDestroy(getNativeHandle()); 132 } 133 } 134 135 /******************************************************************************* 136 * native methods 137 ******************************************************************************/ socketOptionsNew(int domain, int type, int connectTimeoutMs, int keepAliveIntervalSecs, int keepAliveTimeoutSecs, boolean keepAlive)138 private static native long socketOptionsNew(int domain, int type, int connectTimeoutMs, int keepAliveIntervalSecs, int keepAliveTimeoutSecs, boolean keepAlive); 139 socketOptionsDestroy(long elg)140 private static native void socketOptionsDestroy(long elg); 141 }; 142