singrdk/base/Services/NetStack/Channels.Private/IPExpManager.sg

324 lines
12 KiB
Plaintext
Raw Permalink Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note: Provider-side helper for the IP Channel Contract
//
using NetStack.Common;
using System;
using System.Threading;
using System.Net.IP;
using Drivers.Net;
using Microsoft.SingSharp;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Directory;
using NetStack.Contracts;
using NetStack.Runtime;
using System.Collections;
namespace NetStack.Channels.Private
{
2008-11-17 18:29:00 -05:00
public class IPExpManager : StoppableThread
2008-03-05 09:52:00 -05:00
{
private IPModule! ip;
2008-11-17 18:29:00 -05:00
protected override void Run(StopThreadContract.Exp:Ready! terminator)
2008-03-05 09:52:00 -05:00
{
// Here is the channel we use to communicate with
// the NameServer
ServiceProviderContract.Imp! nsImp;
ServiceProviderContract.Exp! nsExp;
ServiceProviderContract.NewChannel(out nsImp, out nsExp);
// Here is our NameServer connection over which we
// receive new client channels. When we become a
// process, this will be present automatically,
// somehow.
DirectoryServiceContract.Imp epNS = DirectoryService.NewClientEndpoint();
try {
epNS.SendRegister(Bitter.FromString2(IPContract.ModuleName), nsImp);
switch receive {
case epNS.AckRegister() :
// All is well.
DebugStub.Print("Registered the IP module as {0}\n",
__arglist(IPContract.ModuleName));
break;
case epNS.NakRegister(ServiceProviderContract.Imp:Start rejectedEP, error) :
// All is very much not well; abort.
DebugStub.Print("Failed to register the IP module.\n");
delete rejectedEP;
delete nsExp;
return;
}
}
finally {
delete epNS;
}
// Here is the set of client channels we service
ESet<IPContract.Exp:ReadyState> epSet = new ESet<IPContract.Exp:ReadyState>();
2008-11-17 18:29:00 -05:00
while (true) {
2008-03-05 09:52:00 -05:00
switch receive {
//
// Don't forget that we're selecting IPContract endpoints
// from the epSet endpoint-set. In each case that we
// receive a message from one of those endpoints, we
// need to remember to put the endpoint back into epSet
// if we want to keep listening to it.
//
case ep.GetDomainName() in epSet :
{
ep.SendDomainName(Bitter.FromString2(ip.HostConfiguration.GetDomainName()));
epSet.Add(ep);
}
break;
case ep.SetDomainName(char[]! in ExHeap name) in epSet :
{
bool success = ip.HostConfiguration.SetDomainName(Bitter.ToString2(name));
delete name;
2008-11-17 18:29:00 -05:00
if (success) {
ep.SendOK();
}
else {
ep.SendErr();
}
2008-03-05 09:52:00 -05:00
epSet.Add(ep);
}
break;
case ep.GetHostName() in epSet :
{
ep.SendHostName(Bitter.FromString2(ip.HostConfiguration.GetHostName()));
epSet.Add(ep);
}
break;
case ep.SetHostName(char[]! in ExHeap name) in epSet :
{
bool success = ip.HostConfiguration.SetHostName(Bitter.ToString2(name));
delete name;
2008-11-17 18:29:00 -05:00
if (success) {
ep.SendOK();
}
else {
ep.SendErr();
}
2008-03-05 09:52:00 -05:00
epSet.Add(ep);
}
break;
case ep.StartDhcp(char[]! in ExHeap ifName) in epSet :
{
IAdapter intf = FindAdapter(Bitter.ToString(ifName));
delete ifName;
if (intf == null) {
ep.SendInterfaceNotFound();
}
else {
ip.HostConfiguration.StartDhcp(intf);
ep.SendOK();
}
epSet.Add(ep);
}
break;
case ep.StopDhcp(char[]! in ExHeap ifName) in epSet :
{
IAdapter intf = FindAdapter(Bitter.ToString(ifName));
delete ifName;
if (intf == null) {
ep.SendInterfaceNotFound();
}
else {
ip.HostConfiguration.StopDhcp(intf);
ep.SendOK();
}
epSet.Add(ep);
}
break;
case ep.IsRunningDhcp(char[]! in ExHeap ifName) in epSet :
{
IAdapter intf = FindAdapter(Bitter.ToString(ifName));
delete ifName;
2008-11-17 18:29:00 -05:00
if (intf == null) {
ep.SendInterfaceNotFound();
}
else {
ep.SendRunning(ip.HostConfiguration.IsRunningDhcp(intf));
}
2008-03-05 09:52:00 -05:00
epSet.Add(ep);
}
break;
case ep.SetInterfaceState(char[]! in ExHeap ifName, uint addr, uint mask, uint gway) in epSet :
{
IAdapter intf = FindAdapter(Bitter.ToString(ifName));
delete ifName;
if (intf == null) {
ep.SendInterfaceNotFound();
}
else {
HostConfiguration h = ip.HostConfiguration;
// Remove existing interface binding, if any
h.Bindings.Flush(intf);
InterfaceIPConfiguration ipconf =
new InterfaceIPConfiguration(new IPv4(addr),
new IPv4(mask),
new IPv4(gway));
2008-11-17 18:29:00 -05:00
if (h.Bindings.Add(intf, ipconf) == false) {
ep.SendErr();
}
else {
ep.SendOK();
}
2008-03-05 09:52:00 -05:00
}
epSet.Add(ep);
}
break;
case ep.GetInterfaces() in epSet :
{
// Count the number of interfaces
ICollection adapters = Core.Instance().GetAdapterInfoCollection();
char[][] in ExHeap names = new[ExHeap] char[adapters.Count][];
int i = 0;
2008-11-17 18:29:00 -05:00
foreach (AdapterInfo! ai in adapters) {
2008-03-05 09:52:00 -05:00
expose (names[i]) {
delete names[i]; // checker does not know its null
names[i] = Bitter.FromString(ai.DeviceName);
}
i++;
}
ep.SendInterfaceList(names);
epSet.Add(ep);
}
break;
case ep.GetInterfaceState(char[]! in ExHeap ifName) in epSet :
{
IAdapter intf = FindAdapter(Bitter.ToString(ifName));
delete ifName;
if (intf == null) {
ep.SendInterfaceNotFound();
}
else {
HostConfiguration h = ip.HostConfiguration;
InterfaceInfo retval = new InterfaceInfo();
// Copy the global interface info
retval.driverName = Bitter.FromString(intf.DriverName);
retval.driverVersion = Bitter.FromString(intf.DriverVersion);
retval.hardwareAddress.Set(intf.HardwareAddress.GetAddressBytes());
retval.linkSpeed = intf.LinkSpeed;
// Copy all the IP config info
ArrayList configs = h.Bindings.GetAdapterIPConfigurations(intf);
InterfaceIPInfo[] in ExHeap ipConfigs = new[ExHeap] InterfaceIPInfo[configs.Count];
int i = 0;
2008-11-17 18:29:00 -05:00
foreach (InterfaceIPConfiguration! ipc in configs) {
2008-03-05 09:52:00 -05:00
ipConfigs[i].address = (uint)ipc.Address;
ipConfigs[i].netmask = (uint)ipc.NetMask;
ipConfigs[i].gateway = (uint)ipc.Gateway;
i++;
}
retval.ipConfigs = ipConfigs;
ep.SendInterfaceState(retval);
}
epSet.Add(ep);
}
break;
case ep.IsLocalAddress(uint addr) in epSet :
{
HostConfiguration h = ip.HostConfiguration;
bool isLocal = h.Bindings.IsLocalAddress(new IPv4(addr));
ep.SendIsLocal(isLocal);
epSet.Add(ep);
}
break;
case ep.ChannelClosed() in epSet :
delete ep;
break;
case nsExp.Connect(ServiceContract.Exp:Start! newEp) :
{
// We expect people to give us TCPContract.Exp instances
IPContract.Exp newIpEp = newEp as IPContract.Exp;
if (newIpEp == null) {
// Invalid contract type. Fail.
nsExp.SendNackConnect(newEp);
}
else {
// Signal ready and start servicing this contract
nsExp.SendAckConnect();
newIpEp.SendReady();
epSet.Add(newIpEp);
}
}
break;
case nsExp.ChannelClosed():
// Exit this thread
2008-11-17 18:29:00 -05:00
goto quit;
case terminator.Terminate():
terminator.SendAckTerminate();
goto quit;
case terminator.ChannelClosed():
goto quit;
2008-03-05 09:52:00 -05:00
}
}
2008-11-17 18:29:00 -05:00
quit:
epSet.Dispose();
delete nsExp;
2008-03-05 09:52:00 -05:00
}
private IAdapter FindAdapter(string deviceName)
{
return Core.Instance().GetAdapterByDeviceName(deviceName);
}
public IPExpManager()
{
ip = (IPModule!)Core.Instance().GetProtocolByName("IP");
base();
}
}
}