move tcp tune code to be shared between windows and unix

This commit is contained in:
rfm 2024-01-30 15:26:34 +00:00
parent ca48e4f5d7
commit 2df0df5450
3 changed files with 191 additions and 185 deletions

View file

@ -101,191 +101,6 @@ static GSFileHandle *fh_stdin = nil;
static GSFileHandle *fh_stdout = nil;
static GSFileHandle *fh_stderr = nil;
@implementation GSTcpTune
static int tuneDelay = 0;
static int tuneLinger = -1;
static int tuneReceive = 0;
static BOOL tuneSendAll = NO;
static int tuneRcvBuf = 0;
static int tuneSndBuf = 0;
+ (void) defaultsChanged: (NSNotification*)n
{
NSUserDefaults *defs = (NSUserDefaults*)[n object];
NSString *str;
if (nil == defs)
{
defs = [NSUserDefaults standardUserDefaults];
}
str = [defs stringForKey: @"GSTcpLinger"];
if (nil == str)
{
tuneLinger = -1;
}
else
{
tuneLinger = [str intValue];
}
tuneRcvBuf = (int)[defs integerForKey: @"GSTcpRcvBuf"];
tuneSndBuf = (int)[defs integerForKey: @"GSTcpSndBuf"];
tuneReceive = (int)[defs integerForKey: @"GSTcpReceive"];
tuneSendAll = [defs boolForKey: @"GSTcpSendAll"];
tuneDelay = [defs boolForKey: @"GSTcpDelay"];
}
+ (void) initialize
{
static BOOL beenHere = NO;
if (NO == beenHere)
{
NSNotificationCenter *nc;
NSUserDefaults *defs;
beenHere = YES;
nc = [NSNotificationCenter defaultCenter];
defs = [NSUserDefaults standardUserDefaults];
[nc addObserver: self
selector: @selector(defaultsChanged:)
name: NSUserDefaultsDidChangeNotification
object: defs];
[self defaultsChanged: nil];
}
}
+ (int) delay
{
return tuneDelay; // Milliseconds to delay close
}
+ (int) recvSize
{
if (tuneReceive > 0)
{
return tuneReceive; // Return receive buffer size
}
if (tuneRcvBuf > 0)
{
return tuneRcvBuf; // Return socket receive buffer size
}
return READ_SIZE; // Return hard-coded default
}
+ (int) sendSize: (int)bytesToSend
{
if (YES == tuneSendAll)
{
return bytesToSend; // Try to send all in one go
}
if (tuneSndBuf > 0 && tuneSndBuf <= bytesToSend)
{
return tuneSndBuf; // Limit to socket send buffer
}
if (NETBUF_SIZE <= bytesToSend)
{
return NETBUF_SIZE; // Limit to hard coded default
}
return bytesToSend;
}
+ (void) tune: (void*)handle with: (id)opts
{
int desc = (int)(intptr_t)handle;
int value;
id o;
#ifndef BROKEN_SO_REUSEADDR
/*
* Under decent systems, SO_REUSEADDR means that the port can be reused
* immediately that this process exits. Under some it means
* that multiple processes can serve the same port simultaneously.
* We don't want that broken behavior!
*/
if (setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value))
< 0)
{
NSDebugMLLog(@"GSTcpTune", @"setsockopt reuseaddr failed for %d", desc);
}
#endif
/*
* Enable tcp-level tracking of whether connection is alive.
*/
value = 1;
if (setsockopt(desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&value, sizeof(value))
< 0)
{
NSDebugMLLog(@"GSTcpTune", @"setsockopt keepalive failed for %d", desc);
}
#define OPTS(X) ([opts isKindOfClass: [NSStream class]] \
? [(NSStream*)opts propertyForKey: X] \
: [(NSDictionary*)opts objectForKey: X])
o = OPTS(@"GSTcpLinger");
value = (o ? [o intValue] : tuneLinger);
if (value >= 0)
{
struct linger l;
l.l_onoff = 1;
l.l_linger = tuneLinger;
if (setsockopt(desc, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0)
{
NSLog(@"Failed to set GSTcpLinger for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpLinger for %d to %d",
desc, value);
}
}
o = OPTS(@"GSTcpRcvBuf");
value = (o ? [o intValue] : tuneRcvBuf);
if (value > 0)
{
/* Set the receive buffer for the socket.
*/
if (setsockopt(desc, SOL_SOCKET, SO_RCVBUF,
(char *)&value, sizeof(value)) < 0)
{
NSLog(@"Failed to set GSTcpRcvBuf for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpRcvBuf for %d to %d",
desc, value);
}
}
o = OPTS(@"GSTcpSndBuf");
value = (o ? [o intValue] : tuneSndBuf);
if (value > 0)
{
/* Set the send buffer for the socket.
*/
if (setsockopt(desc, SOL_SOCKET, SO_SNDBUF,
(char *)&value, sizeof(value)) < 0)
{
NSLog(@"Failed to set GSTcpSndBuf for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpSndBuf for %d to %d",
desc, value);
}
}
}
@end
// Key to info dictionary for operation mode.
static NSString* NotificationKey = @"NSFileHandleNotificationKey";

View file

@ -72,6 +72,196 @@
#define OPTLEN socklen_t
#endif // _WIN32
// Maximum data in single I/O operation
#define NETBUF_SIZE (1024 * 16)
#define READ_SIZE NETBUF_SIZE*10
@implementation GSTcpTune
static int tuneDelay = 0;
static int tuneLinger = -1;
static int tuneReceive = 0;
static BOOL tuneSendAll = NO;
static int tuneRcvBuf = 0;
static int tuneSndBuf = 0;
+ (void) defaultsChanged: (NSNotification*)n
{
NSUserDefaults *defs = (NSUserDefaults*)[n object];
NSString *str;
if (nil == defs)
{
defs = [NSUserDefaults standardUserDefaults];
}
str = [defs stringForKey: @"GSTcpLinger"];
if (nil == str)
{
tuneLinger = -1;
}
else
{
tuneLinger = [str intValue];
}
tuneRcvBuf = (int)[defs integerForKey: @"GSTcpRcvBuf"];
tuneSndBuf = (int)[defs integerForKey: @"GSTcpSndBuf"];
tuneReceive = (int)[defs integerForKey: @"GSTcpReceive"];
tuneSendAll = [defs boolForKey: @"GSTcpSendAll"];
tuneDelay = [defs boolForKey: @"GSTcpDelay"];
}
+ (void) initialize
{
static BOOL beenHere = NO;
if (NO == beenHere)
{
NSNotificationCenter *nc;
NSUserDefaults *defs;
beenHere = YES;
nc = [NSNotificationCenter defaultCenter];
defs = [NSUserDefaults standardUserDefaults];
[nc addObserver: self
selector: @selector(defaultsChanged:)
name: NSUserDefaultsDidChangeNotification
object: defs];
[self defaultsChanged: nil];
}
}
+ (int) delay
{
return tuneDelay; // Milliseconds to delay close
}
+ (int) recvSize
{
if (tuneReceive > 0)
{
return tuneReceive; // Return receive buffer size
}
if (tuneRcvBuf > 0)
{
return tuneRcvBuf; // Return socket receive buffer size
}
return READ_SIZE; // Return hard-coded default
}
+ (int) sendSize: (int)bytesToSend
{
if (YES == tuneSendAll)
{
return bytesToSend; // Try to send all in one go
}
if (tuneSndBuf > 0 && tuneSndBuf <= bytesToSend)
{
return tuneSndBuf; // Limit to socket send buffer
}
if (NETBUF_SIZE <= bytesToSend)
{
return NETBUF_SIZE; // Limit to hard coded default
}
return bytesToSend;
}
+ (void) tune: (void*)handle with: (id)opts
{
int desc = (int)(intptr_t)handle;
int value;
id o;
#ifndef BROKEN_SO_REUSEADDR
/*
* Under decent systems, SO_REUSEADDR means that the port can be reused
* immediately that this process exits. Under some it means
* that multiple processes can serve the same port simultaneously.
* We don't want that broken behavior!
*/
if (setsockopt(desc, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value))
< 0)
{
NSDebugMLLog(@"GSTcpTune", @"setsockopt reuseaddr failed for %d", desc);
}
#endif
/*
* Enable tcp-level tracking of whether connection is alive.
*/
value = 1;
if (setsockopt(desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&value, sizeof(value))
< 0)
{
NSDebugMLLog(@"GSTcpTune", @"setsockopt keepalive failed for %d", desc);
}
#define OPTS(X) ([opts isKindOfClass: [NSStream class]] \
? [(NSStream*)opts propertyForKey: X] \
: [(NSDictionary*)opts objectForKey: X])
o = OPTS(@"GSTcpLinger");
value = (o ? [o intValue] : tuneLinger);
if (value >= 0)
{
struct linger l;
l.l_onoff = 1;
l.l_linger = tuneLinger;
if (setsockopt(desc, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0)
{
NSLog(@"Failed to set GSTcpLinger for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpLinger for %d to %d",
desc, value);
}
}
o = OPTS(@"GSTcpRcvBuf");
value = (o ? [o intValue] : tuneRcvBuf);
if (value > 0)
{
/* Set the receive buffer for the socket.
*/
if (setsockopt(desc, SOL_SOCKET, SO_RCVBUF,
(char *)&value, sizeof(value)) < 0)
{
NSLog(@"Failed to set GSTcpRcvBuf for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpRcvBuf for %d to %d",
desc, value);
}
}
o = OPTS(@"GSTcpSndBuf");
value = (o ? [o intValue] : tuneSndBuf);
if (value > 0)
{
/* Set the send buffer for the socket.
*/
if (setsockopt(desc, SOL_SOCKET, SO_SNDBUF,
(char *)&value, sizeof(value)) < 0)
{
NSLog(@"Failed to set GSTcpSndBuf for %d to %d: %@",
desc, value, [NSError _last]);
}
else
{
NSDebugMLLog(@"GSTcpTune", @"Set GSTcpSndBuf for %d to %d",
desc, value);
}
}
}
@end
unsigned
GSPrivateSockaddrLength(struct sockaddr *addr)
{

View file

@ -37,6 +37,7 @@
#import "Foundation/NSHost.h"
#import "Foundation/NSByteOrder.h"
#import "Foundation/NSProcessInfo.h"
#import "Foundation/NSStream.h"
#import "Foundation/NSUserDefaults.h"
#import "Foundation/NSDebug.h"