* Made it work and build again after recent network stack changes.
* Implement "close" command that actively closes the server socket, or does an simultaneous close. Even though this triggers an "endless conversation" between two time-wait endpoints on Haiku, it works fine in the shell. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25225 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
|
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -7,6 +7,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define _KERNEL_DEBUG_H
|
||||||
|
// avoid including the private kernel debug.h header
|
||||||
|
|
||||||
#include "argv.h"
|
#include "argv.h"
|
||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
@@ -93,6 +96,8 @@ static bigtime_t sStartTime;
|
|||||||
static double sRandomReorder = 0.0;
|
static double sRandomReorder = 0.0;
|
||||||
static set<uint32> sReorderList;
|
static set<uint32> sReorderList;
|
||||||
static bool sSimultaneousConnect = false;
|
static bool sSimultaneousConnect = false;
|
||||||
|
static bool sSimultaneousClose = false;
|
||||||
|
static bool sServerActiveClose = false;
|
||||||
|
|
||||||
static struct net_domain sDomain = {
|
static struct net_domain sDomain = {
|
||||||
"ipv4",
|
"ipv4",
|
||||||
@@ -103,23 +108,36 @@ static struct net_domain sDomain = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool
|
static bool
|
||||||
is_server(const sockaddr* addr)
|
is_server(const sockaddr* addr)
|
||||||
{
|
{
|
||||||
return ((sockaddr_in*)addr)->sin_port == htons(1024);
|
return ((sockaddr_in*)addr)->sin_port == htons(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
static uint8
|
||||||
is_syn(net_buffer* buffer)
|
tcp_segment_flags(net_buffer* buffer)
|
||||||
{
|
{
|
||||||
NetBufferHeaderReader<tcp_header> bufferHeader(buffer);
|
NetBufferHeaderReader<tcp_header> bufferHeader(buffer);
|
||||||
if (bufferHeader.Status() < B_OK)
|
if (bufferHeader.Status() < B_OK)
|
||||||
return bufferHeader.Status();
|
return bufferHeader.Status();
|
||||||
|
|
||||||
tcp_header &header = bufferHeader.Data();
|
tcp_header &header = bufferHeader.Data();
|
||||||
|
return header.flags;
|
||||||
|
}
|
||||||
|
|
||||||
return (header.flags & TCP_FLAG_SYNCHRONIZE) != 0;
|
|
||||||
|
static bool
|
||||||
|
is_syn(net_buffer* buffer)
|
||||||
|
{
|
||||||
|
return (tcp_segment_flags(buffer) & TCP_FLAG_SYNCHRONIZE) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
is_fin(net_buffer* buffer)
|
||||||
|
{
|
||||||
|
return (tcp_segment_flags(buffer) & TCP_FLAG_FINISH) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -155,6 +173,12 @@ delete_object_cache(object_cache *cache)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
scheduler_enqueue_in_run_queue(struct thread *thread)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - stack
|
// #pragma mark - stack
|
||||||
|
|
||||||
|
|
||||||
@@ -193,33 +217,53 @@ register_domain_receiving_protocol(int family, int type, const char *moduleName)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
dummy_is_syscall(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
dummy_is_restarted_syscall(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dummy_store_syscall_restart_timeout(bigtime_t timeout)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static net_stack_module_info gNetStackModule = {
|
static net_stack_module_info gNetStackModule = {
|
||||||
{
|
{
|
||||||
NET_STACK_MODULE_NAME,
|
NET_STACK_MODULE_NAME,
|
||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
NULL, //register_domain,
|
NULL, // register_domain,
|
||||||
NULL, //unregister_domain,
|
NULL, // unregister_domain,
|
||||||
get_domain,
|
get_domain,
|
||||||
|
|
||||||
register_domain_protocols,
|
register_domain_protocols,
|
||||||
register_domain_datalink_protocols,
|
register_domain_datalink_protocols,
|
||||||
register_domain_receiving_protocol,
|
register_domain_receiving_protocol,
|
||||||
|
|
||||||
NULL, //get_domain_receiving_protocol,
|
NULL, // get_domain_receiving_protocol,
|
||||||
NULL, //put_domain_receiving_protocol,
|
NULL, // put_domain_receiving_protocol,
|
||||||
|
|
||||||
NULL, //register_device_deframer,
|
NULL, // register_device_deframer,
|
||||||
NULL, //unregister_device_deframer,
|
NULL, // unregister_device_deframer,
|
||||||
NULL, //register_domain_device_handler,
|
NULL, // register_domain_device_handler,
|
||||||
NULL, //register_device_handler,
|
NULL, // register_device_handler,
|
||||||
NULL, //unregister_device_handler,
|
NULL, // unregister_device_handler,
|
||||||
NULL, //register_device_monitor,
|
NULL, // register_device_monitor,
|
||||||
NULL, //unregister_device_monitor,
|
NULL, // unregister_device_monitor,
|
||||||
NULL, //device_link_changed,
|
NULL, // device_link_changed,
|
||||||
NULL, //device_removed,
|
NULL, // device_removed,
|
||||||
NULL, //device_enqueue_buffer,
|
NULL, // device_enqueue_buffer,
|
||||||
|
|
||||||
notify_socket,
|
notify_socket,
|
||||||
|
|
||||||
@@ -236,6 +280,11 @@ static net_stack_module_info gNetStackModule = {
|
|||||||
set_timer,
|
set_timer,
|
||||||
cancel_timer,
|
cancel_timer,
|
||||||
is_timer_active,
|
is_timer_active,
|
||||||
|
|
||||||
|
dummy_is_syscall,
|
||||||
|
dummy_is_restarted_syscall,
|
||||||
|
dummy_store_syscall_restart_timeout,
|
||||||
|
NULL, // restore_syscall_restart_timeout
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -621,23 +670,23 @@ net_socket_module_info gNetSocketModule = {
|
|||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
NULL, //socket_open,
|
NULL, // open,
|
||||||
NULL, //socket_close,
|
NULL, // close,
|
||||||
NULL, //socket_free,
|
NULL, // free,
|
||||||
|
|
||||||
NULL, //socket_readv,
|
NULL, // readv,
|
||||||
NULL, //socket_writev,
|
NULL, // writev,
|
||||||
NULL, //socket_control,
|
NULL, // control,
|
||||||
|
|
||||||
NULL, //socket_read_avail,
|
NULL, // read_avail,
|
||||||
NULL, //socket_send_avail,
|
NULL, // send_avail,
|
||||||
|
|
||||||
NULL, //socket_send_data,
|
NULL, // send_data,
|
||||||
NULL, //socket_receive_data,
|
NULL, // receive_data,
|
||||||
|
|
||||||
NULL, //get_option,
|
NULL, // get_option,
|
||||||
NULL, //set_option,
|
NULL, // set_option,
|
||||||
NULL, //socket_get_next_stat,
|
NULL, // get_next_stat,
|
||||||
|
|
||||||
// connections
|
// connections
|
||||||
socket_spawn_pending,
|
socket_spawn_pending,
|
||||||
@@ -648,22 +697,23 @@ net_socket_module_info gNetSocketModule = {
|
|||||||
socket_connected,
|
socket_connected,
|
||||||
|
|
||||||
// notifications
|
// notifications
|
||||||
NULL, //socket_request_notification,
|
NULL, // request_notification,
|
||||||
NULL, //socket_cancel_notification,
|
NULL, // cancel_notification,
|
||||||
socket_notify,
|
socket_notify,
|
||||||
|
|
||||||
// standard socket API
|
// standard socket API
|
||||||
NULL, //socket_accept,
|
NULL, // accept,
|
||||||
NULL, //socket_bind,
|
NULL, // bind,
|
||||||
NULL, //socket_connect,
|
NULL, // connect,
|
||||||
NULL, //socket_getpeername,
|
NULL, // getpeername,
|
||||||
NULL, //socket_getsockname,
|
NULL, // getsockname,
|
||||||
NULL, //socket_getsockopt,
|
NULL, // getsockopt,
|
||||||
NULL, //socket_listen,
|
NULL, // listen,
|
||||||
NULL, //socket_recv,
|
NULL, // receive,
|
||||||
NULL, //socket_send,
|
NULL, // send,
|
||||||
NULL, //socket_setsockopt,
|
NULL, // setsockopt,
|
||||||
NULL, //socket_shutdown,
|
NULL, // shutdown,
|
||||||
|
NULL, // socketpair
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1046,6 +1096,8 @@ net_protocol_module_info gDomainModule = {
|
|||||||
0,
|
0,
|
||||||
std_ops
|
std_ops
|
||||||
},
|
},
|
||||||
|
NET_PROTOCOL_ATOMIC_MESSAGES,
|
||||||
|
|
||||||
NULL, // init
|
NULL, // init
|
||||||
NULL, // uninit
|
NULL, // uninit
|
||||||
domain_open,
|
domain_open,
|
||||||
@@ -1071,6 +1123,8 @@ net_protocol_module_info gDomainModule = {
|
|||||||
NULL, // deliver_data
|
NULL, // deliver_data
|
||||||
domain_error,
|
domain_error,
|
||||||
domain_error_reply,
|
domain_error_reply,
|
||||||
|
NULL, // attach_ancillary_data
|
||||||
|
NULL, // process_ancillary_data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1094,7 +1148,8 @@ receiving_thread(void* _data)
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
context->lock.Lock();
|
context->lock.Lock();
|
||||||
net_buffer* buffer = (net_buffer*)list_remove_head_item(&context->list);
|
net_buffer* buffer = (net_buffer*)list_remove_head_item(
|
||||||
|
&context->list);
|
||||||
context->lock.Unlock();
|
context->lock.Unlock();
|
||||||
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
@@ -1108,13 +1163,17 @@ receiving_thread(void* _data)
|
|||||||
address.sin_port = htons(1023);
|
address.sin_port = htons(1023);
|
||||||
address.sin_addr.s_addr = htonl(0xc0a80001);
|
address.sin_addr.s_addr = htonl(0xc0a80001);
|
||||||
|
|
||||||
status_t status = socket_connect(gServerSocket, (struct sockaddr *)&address,
|
status_t status = socket_connect(gServerSocket,
|
||||||
sizeof(struct sockaddr));
|
(struct sockaddr *)&address, sizeof(struct sockaddr));
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
fprintf(stderr, "tcp_tester: simultaneous connect failed: %s\n", strerror(status));
|
fprintf(stderr, "tcp_tester: simultaneous connect failed: %s\n", strerror(status));
|
||||||
|
|
||||||
sSimultaneousConnect = false;
|
sSimultaneousConnect = false;
|
||||||
}
|
}
|
||||||
|
if (sSimultaneousClose && !context->server && is_fin(buffer)) {
|
||||||
|
close_protocol(gClientSocket->first_protocol);
|
||||||
|
sSimultaneousClose = false;
|
||||||
|
}
|
||||||
if ((sRandomReorder > 0.0
|
if ((sRandomReorder > 0.0
|
||||||
|| sReorderList.find(sPacketNumber) != sReorderList.end())
|
|| sReorderList.find(sPacketNumber) != sReorderList.end())
|
||||||
&& reorderBuffer == NULL
|
&& reorderBuffer == NULL
|
||||||
@@ -1159,6 +1218,12 @@ server_thread(void*)
|
|||||||
while ((bytesRead = socket_recv(connectionSocket, buffer,
|
while ((bytesRead = socket_recv(connectionSocket, buffer,
|
||||||
sizeof(buffer), 0)) > 0) {
|
sizeof(buffer), 0)) > 0) {
|
||||||
printf("server: received %ld bytes\n", bytesRead);
|
printf("server: received %ld bytes\n", bytesRead);
|
||||||
|
|
||||||
|
if (sServerActiveClose) {
|
||||||
|
printf("server: active close\n");
|
||||||
|
close_protocol(connectionSocket->first_protocol);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (bytesRead < 0)
|
if (bytesRead < 0)
|
||||||
printf("server: receiving failed: %s\n", strerror(bytesRead));
|
printf("server: receiving failed: %s\n", strerror(bytesRead));
|
||||||
@@ -1183,7 +1248,7 @@ setup_server()
|
|||||||
address.sin_port = htons(1024);
|
address.sin_port = htons(1024);
|
||||||
address.sin_addr.s_addr = INADDR_ANY;
|
address.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
status_t status = socket_bind(gServerSocket, (struct sockaddr *)&address,
|
status_t status = socket_bind(gServerSocket, (struct sockaddr*)&address,
|
||||||
sizeof(struct sockaddr));
|
sizeof(struct sockaddr));
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
fprintf(stderr, "tcp_tester: cannot bind server: %s\n", strerror(status));
|
fprintf(stderr, "tcp_tester: cannot bind server: %s\n", strerror(status));
|
||||||
@@ -1337,6 +1402,32 @@ do_send(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_close(int argc, char** argv)
|
||||||
|
{
|
||||||
|
sSimultaneousClose = false;
|
||||||
|
sServerActiveClose = true;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
if (!strcmp(argv[1], "-s"))
|
||||||
|
sSimultaneousClose = true;
|
||||||
|
else {
|
||||||
|
fprintf(stderr, "usage: close [-s]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gClientSocket->send.timeout = 0;
|
||||||
|
|
||||||
|
char buffer[32767] = {'q'};
|
||||||
|
ssize_t bytesWritten = socket_send(gClientSocket, buffer, sizeof(buffer), 0);
|
||||||
|
if (bytesWritten < B_OK) {
|
||||||
|
fprintf(stderr, "failed sending buffer: %s\n", strerror(bytesWritten));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_drop(int argc, char** argv)
|
do_drop(int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -1493,6 +1584,7 @@ do_dprintf(int argc, char** argv)
|
|||||||
static cmd_entry sBuiltinCommands[] = {
|
static cmd_entry sBuiltinCommands[] = {
|
||||||
{"connect", do_connect, "Connects the client"},
|
{"connect", do_connect, "Connects the client"},
|
||||||
{"send", do_send, "Sends data from the client to the server"},
|
{"send", do_send, "Sends data from the client to the server"},
|
||||||
|
{"close", do_close, "Performs an active or simultaneous close"},
|
||||||
{"dprintf", do_dprintf, "Toggles debug output"},
|
{"dprintf", do_dprintf, "Toggles debug output"},
|
||||||
{"drop", do_drop, "Lets you drop packets during transfer"},
|
{"drop", do_drop, "Lets you drop packets during transfer"},
|
||||||
{"reorder", do_reorder, "Lets you reorder packets during transfer"},
|
{"reorder", do_reorder, "Lets you reorder packets during transfer"},
|
||||||
@@ -1514,6 +1606,9 @@ do_help(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
@@ -1524,10 +1619,10 @@ main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_add_builtin_module((module_info *)&gNetStackModule);
|
_add_builtin_module((module_info*)&gNetStackModule);
|
||||||
_add_builtin_module((module_info *)&gNetBufferModule);
|
_add_builtin_module((module_info*)&gNetBufferModule);
|
||||||
_add_builtin_module((module_info *)&gNetSocketModule);
|
_add_builtin_module((module_info*)&gNetSocketModule);
|
||||||
_add_builtin_module((module_info *)&gNetDatalinkModule);
|
_add_builtin_module((module_info*)&gNetDatalinkModule);
|
||||||
_add_builtin_module(modules[0]);
|
_add_builtin_module(modules[0]);
|
||||||
if (_get_builtin_dependencies() < B_OK) {
|
if (_get_builtin_dependencies() < B_OK) {
|
||||||
fprintf(stderr, "tcp_tester: Could not initialize modules: %s\n",
|
fprintf(stderr, "tcp_tester: Could not initialize modules: %s\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user