* 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:
parent
cb2afe5cc7
commit
c927bf5c49
@ -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.
|
||||
*
|
||||
* Authors:
|
||||
@ -7,6 +7,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#define _KERNEL_DEBUG_H
|
||||
// avoid including the private kernel debug.h header
|
||||
|
||||
#include "argv.h"
|
||||
#include "tcp.h"
|
||||
#include "utility.h"
|
||||
@ -93,6 +96,8 @@ static bigtime_t sStartTime;
|
||||
static double sRandomReorder = 0.0;
|
||||
static set<uint32> sReorderList;
|
||||
static bool sSimultaneousConnect = false;
|
||||
static bool sSimultaneousClose = false;
|
||||
static bool sServerActiveClose = false;
|
||||
|
||||
static struct net_domain sDomain = {
|
||||
"ipv4",
|
||||
@ -103,23 +108,36 @@ static struct net_domain sDomain = {
|
||||
};
|
||||
|
||||
|
||||
bool
|
||||
static bool
|
||||
is_server(const sockaddr* addr)
|
||||
{
|
||||
return ((sockaddr_in*)addr)->sin_port == htons(1024);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_syn(net_buffer* buffer)
|
||||
static uint8
|
||||
tcp_segment_flags(net_buffer* buffer)
|
||||
{
|
||||
NetBufferHeaderReader<tcp_header> bufferHeader(buffer);
|
||||
if (bufferHeader.Status() < B_OK)
|
||||
return bufferHeader.Status();
|
||||
|
||||
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
|
||||
|
||||
|
||||
@ -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 = {
|
||||
{
|
||||
NET_STACK_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
NULL, //register_domain,
|
||||
NULL, //unregister_domain,
|
||||
NULL, // register_domain,
|
||||
NULL, // unregister_domain,
|
||||
get_domain,
|
||||
|
||||
register_domain_protocols,
|
||||
register_domain_datalink_protocols,
|
||||
register_domain_receiving_protocol,
|
||||
|
||||
NULL, //get_domain_receiving_protocol,
|
||||
NULL, //put_domain_receiving_protocol,
|
||||
NULL, // get_domain_receiving_protocol,
|
||||
NULL, // put_domain_receiving_protocol,
|
||||
|
||||
NULL, //register_device_deframer,
|
||||
NULL, //unregister_device_deframer,
|
||||
NULL, //register_domain_device_handler,
|
||||
NULL, //register_device_handler,
|
||||
NULL, //unregister_device_handler,
|
||||
NULL, //register_device_monitor,
|
||||
NULL, //unregister_device_monitor,
|
||||
NULL, //device_link_changed,
|
||||
NULL, //device_removed,
|
||||
NULL, //device_enqueue_buffer,
|
||||
NULL, // register_device_deframer,
|
||||
NULL, // unregister_device_deframer,
|
||||
NULL, // register_domain_device_handler,
|
||||
NULL, // register_device_handler,
|
||||
NULL, // unregister_device_handler,
|
||||
NULL, // register_device_monitor,
|
||||
NULL, // unregister_device_monitor,
|
||||
NULL, // device_link_changed,
|
||||
NULL, // device_removed,
|
||||
NULL, // device_enqueue_buffer,
|
||||
|
||||
notify_socket,
|
||||
|
||||
@ -236,6 +280,11 @@ static net_stack_module_info gNetStackModule = {
|
||||
set_timer,
|
||||
cancel_timer,
|
||||
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,
|
||||
std_ops
|
||||
},
|
||||
NULL, //socket_open,
|
||||
NULL, //socket_close,
|
||||
NULL, //socket_free,
|
||||
NULL, // open,
|
||||
NULL, // close,
|
||||
NULL, // free,
|
||||
|
||||
NULL, //socket_readv,
|
||||
NULL, //socket_writev,
|
||||
NULL, //socket_control,
|
||||
NULL, // readv,
|
||||
NULL, // writev,
|
||||
NULL, // control,
|
||||
|
||||
NULL, //socket_read_avail,
|
||||
NULL, //socket_send_avail,
|
||||
NULL, // read_avail,
|
||||
NULL, // send_avail,
|
||||
|
||||
NULL, //socket_send_data,
|
||||
NULL, //socket_receive_data,
|
||||
NULL, // send_data,
|
||||
NULL, // receive_data,
|
||||
|
||||
NULL, //get_option,
|
||||
NULL, //set_option,
|
||||
NULL, //socket_get_next_stat,
|
||||
NULL, // get_option,
|
||||
NULL, // set_option,
|
||||
NULL, // get_next_stat,
|
||||
|
||||
// connections
|
||||
socket_spawn_pending,
|
||||
@ -648,22 +697,23 @@ net_socket_module_info gNetSocketModule = {
|
||||
socket_connected,
|
||||
|
||||
// notifications
|
||||
NULL, //socket_request_notification,
|
||||
NULL, //socket_cancel_notification,
|
||||
NULL, // request_notification,
|
||||
NULL, // cancel_notification,
|
||||
socket_notify,
|
||||
|
||||
// standard socket API
|
||||
NULL, //socket_accept,
|
||||
NULL, //socket_bind,
|
||||
NULL, //socket_connect,
|
||||
NULL, //socket_getpeername,
|
||||
NULL, //socket_getsockname,
|
||||
NULL, //socket_getsockopt,
|
||||
NULL, //socket_listen,
|
||||
NULL, //socket_recv,
|
||||
NULL, //socket_send,
|
||||
NULL, //socket_setsockopt,
|
||||
NULL, //socket_shutdown,
|
||||
NULL, // accept,
|
||||
NULL, // bind,
|
||||
NULL, // connect,
|
||||
NULL, // getpeername,
|
||||
NULL, // getsockname,
|
||||
NULL, // getsockopt,
|
||||
NULL, // listen,
|
||||
NULL, // receive,
|
||||
NULL, // send,
|
||||
NULL, // setsockopt,
|
||||
NULL, // shutdown,
|
||||
NULL, // socketpair
|
||||
};
|
||||
|
||||
|
||||
@ -1046,6 +1096,8 @@ net_protocol_module_info gDomainModule = {
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
NET_PROTOCOL_ATOMIC_MESSAGES,
|
||||
|
||||
NULL, // init
|
||||
NULL, // uninit
|
||||
domain_open,
|
||||
@ -1071,6 +1123,8 @@ net_protocol_module_info gDomainModule = {
|
||||
NULL, // deliver_data
|
||||
domain_error,
|
||||
domain_error_reply,
|
||||
NULL, // attach_ancillary_data
|
||||
NULL, // process_ancillary_data
|
||||
};
|
||||
|
||||
|
||||
@ -1094,7 +1148,8 @@ receiving_thread(void* _data)
|
||||
|
||||
while (true) {
|
||||
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();
|
||||
|
||||
if (buffer == NULL)
|
||||
@ -1108,13 +1163,17 @@ receiving_thread(void* _data)
|
||||
address.sin_port = htons(1023);
|
||||
address.sin_addr.s_addr = htonl(0xc0a80001);
|
||||
|
||||
status_t status = socket_connect(gServerSocket, (struct sockaddr *)&address,
|
||||
sizeof(struct sockaddr));
|
||||
status_t status = socket_connect(gServerSocket,
|
||||
(struct sockaddr *)&address, sizeof(struct sockaddr));
|
||||
if (status < B_OK)
|
||||
fprintf(stderr, "tcp_tester: simultaneous connect failed: %s\n", strerror(status));
|
||||
|
||||
sSimultaneousConnect = false;
|
||||
}
|
||||
if (sSimultaneousClose && !context->server && is_fin(buffer)) {
|
||||
close_protocol(gClientSocket->first_protocol);
|
||||
sSimultaneousClose = false;
|
||||
}
|
||||
if ((sRandomReorder > 0.0
|
||||
|| sReorderList.find(sPacketNumber) != sReorderList.end())
|
||||
&& reorderBuffer == NULL
|
||||
@ -1159,6 +1218,12 @@ server_thread(void*)
|
||||
while ((bytesRead = socket_recv(connectionSocket, buffer,
|
||||
sizeof(buffer), 0)) > 0) {
|
||||
printf("server: received %ld bytes\n", bytesRead);
|
||||
|
||||
if (sServerActiveClose) {
|
||||
printf("server: active close\n");
|
||||
close_protocol(connectionSocket->first_protocol);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (bytesRead < 0)
|
||||
printf("server: receiving failed: %s\n", strerror(bytesRead));
|
||||
@ -1183,7 +1248,7 @@ setup_server()
|
||||
address.sin_port = htons(1024);
|
||||
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));
|
||||
if (status < B_OK) {
|
||||
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
|
||||
do_drop(int argc, char** argv)
|
||||
{
|
||||
@ -1493,6 +1584,7 @@ do_dprintf(int argc, char** argv)
|
||||
static cmd_entry sBuiltinCommands[] = {
|
||||
{"connect", do_connect, "Connects the client"},
|
||||
{"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"},
|
||||
{"drop", do_drop, "Lets you drop 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
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
@ -1524,10 +1619,10 @@ main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
_add_builtin_module((module_info *)&gNetStackModule);
|
||||
_add_builtin_module((module_info *)&gNetBufferModule);
|
||||
_add_builtin_module((module_info *)&gNetSocketModule);
|
||||
_add_builtin_module((module_info *)&gNetDatalinkModule);
|
||||
_add_builtin_module((module_info*)&gNetStackModule);
|
||||
_add_builtin_module((module_info*)&gNetBufferModule);
|
||||
_add_builtin_module((module_info*)&gNetSocketModule);
|
||||
_add_builtin_module((module_info*)&gNetDatalinkModule);
|
||||
_add_builtin_module(modules[0]);
|
||||
if (_get_builtin_dependencies() < B_OK) {
|
||||
fprintf(stderr, "tcp_tester: Could not initialize modules: %s\n",
|
||||
|
Loading…
Reference in New Issue
Block a user