singrdk/base/Contracts/NetStack.Contracts/TCPConnectionContract.sg

257 lines
8.1 KiB
Plaintext
Raw Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: Contract definition for TCP channels
//
using Microsoft.Singularity.Channels;
using System;
namespace NetStack.Contracts
{
2008-11-17 18:29:00 -05:00
public enum TcpError
{
Unknown = 1,
AlreadyConnected, // this connection is already in use
Refused, // the receiving host actively refused the connection
Reset, // the connection was reset
Timeout, // no response was received
ProtocolViolation, // we received a TCP segment that is not acceptable in the current state
ResourcesExhausted, // out of memory, etc.
Closed, // remote peer has closed socket
}
2008-03-05 09:52:00 -05:00
public contract TcpConnectionContract
{
// Requests
in message Connect(uint dstIP, ushort dstPort);
in message BindLocalEndPoint(uint dstIP, ushort dstPort);
//
// Initial state; there is a gratuitous Ready message to
// ensure the Exp side has been connected before it accepts
// any messages.
//
out message Ready();
state Start : Ready! -> ReadyState;
state ReadyState : one
{
Connect? -> ConnectResult; // Can connect without binding first
BindLocalEndPoint? -> BindResult; // Can't listen without binding first
Close? -> Closed;
}
//
// Binding to a local endpoint
//
state BindResult : one
{
OK! -> Bound;
InvalidEndPoint! -> ReadyState;
}
in message Listen(int backlog);
state Bound : one
{
Listen? -> ListenResult;
Connect? -> ConnectResult;
Close? -> Closed;
}
//
// Attempts to connect to a remote host
//
out message OK();
out message CouldNotConnect(TcpError error);
state ConnectResult : one
{
CouldNotConnect! -> ReadyState;
OK! -> Connected;
}
//
// Attempts to listen for inbound connections
//
out message CouldNotListen();
state ListenResult : one
{
CouldNotListen! -> ReadyState;
OK! -> Listening;
}
out message InvalidEndPoint();
in message GetLocalAddress();
in message GetLocalPort();
in message Accept(TcpConnectionContract.Exp:PreConnected! newConnection);
in message IsSessionAvailable(); // Is there a new session waiting to be serviced?
out message IPAddress(uint ip);
out message Port(ushort port);
out message SessionIsAvailable(bool isAvailable);
state Listening : one
{
GetLocalAddress? -> IPAddress! -> Listening;
GetLocalPort? -> Port! -> Listening;
IsSessionAvailable? -> SessionIsAvailable! -> Listening;
Accept? -> OK! -> Listening; // Blocks until a connection is received
Close? -> Closed;
}
//
// The pre-connected state exists so we can confirm that the endpoint
// has been wired to the NetStack before accepting messages on it
//
state PreConnected : Ready! -> Connected;
//
// Operations on an established connection
//
// Requests
in message Read(); // Read as much data as possible without blocking
in message PollRead(int timeout); // Wait up to timeout ms for data
in message IsDataAvailable(); // Is there queued data that can be read immediately?
in message Write(byte[]! in ExHeap data);
in message Close(); // Performs a non-blocking but graceful shutdown
in message Abort(); // Performs an immediate, hard close (unsent data is discarded)
in message GetRemoteAddress();
in message GetRemotePort();
in message DoneSending();
in message DoneReceiving();
// Response messages
out message ConnectionClosed(); // Connection has been shut down
out message NoData(); // There was nothing to read
out message NoMoreData(); // Will never be more data
out message CantSend(); // Remote side refuses more data
out message Data(byte[]! in ExHeap data);
out message DataIsAvailable(bool isAvailable);
state Connected : one
{
Read? -> ReadResult;
PollRead? -> PollReadResult;
Write? -> WriteResult;
IsDataAvailable? -> (DataIsAvailable!) -> Connected;
GetLocalAddress? -> IPAddress! -> Connected;
GetLocalPort? -> Port! -> Connected;
GetRemoteAddress? -> IPAddress! -> Connected;
GetRemotePort? -> Port! -> Connected;
DoneSending? -> ReceiveOnly;
DoneReceiving? -> SendOnly;
Close? -> Closed;
Abort? -> Closed;
}
state ReadResult : one
{
Data! -> Connected;
// This indicates that there will never be any more
// data, but that sending is still allowed
NoMoreData! -> SendOnly;
// This indicates that sending has been closed by the
// remote side
ConnectionClosed! -> Zombie;
}
state PollReadResult : one
{
Data! -> Connected;
// No data available within the poll window; try again
NoData! -> Connected;
NoMoreData! -> SendOnly;
ConnectionClosed! -> Zombie;
}
state WriteResult : one
{
OK! -> Connected;
// This indicates that writing has been closed by the
// remote side, but reading is still allowed.
CantSend! -> ReceiveOnly;
}
//
// Operations on a receive-only connection (send side has been closed)
//
state ReceiveOnly : one
{
Read? -> ROReadResult;
PollRead? -> ROPollReadResult;
IsDataAvailable? -> (DataIsAvailable!) -> ReceiveOnly;
GetLocalAddress? -> IPAddress! -> ReceiveOnly;
GetLocalPort? -> Port! -> ReceiveOnly;
GetRemoteAddress? -> IPAddress! -> ReceiveOnly;
GetRemotePort? -> Port! -> ReceiveOnly;
DoneReceiving? -> Zombie;
Close? -> Closed;
Abort? -> Closed;
}
state ROReadResult : one
{
Data! -> ReceiveOnly;
// If there is no more data, there's nothing more to do.
NoMoreData! -> Zombie;
}
state ROPollReadResult : one
{
Data! -> ReceiveOnly;
NoData! -> ReceiveOnly;
NoMoreData! -> Zombie;
}
//
// Operations on a send-only connection (receive side has been closed)
//
state SendOnly : one
{
Write? -> SOWriteResult;
GetLocalAddress? -> IPAddress! -> SendOnly;
GetLocalPort? -> Port! -> SendOnly;
GetRemoteAddress? -> IPAddress! -> SendOnly;
GetRemotePort? -> Port! -> SendOnly;
DoneSending? -> Zombie;
Close? -> Closed;
Abort? -> Closed;
}
state SOWriteResult : one
{
OK! -> SendOnly;
// Remote side refuses further data
CantSend! -> Zombie;
}
//
// Zombied connection (nothing left to do but user hasn't explicitly
// closed yet)
//
state Zombie : one
{
Close? -> Closed; // Wrap up gracefully
Abort? -> Closed; // Drop any unsent data
}
state Closed : {} // Nothing is acceptable here
}
}