Thank you, Kristian Knuechel, for reporting a bug (now fixed).

Fixed the build.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14359 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2005-10-12 10:06:12 +00:00
parent dea7a63c17
commit a89ad654b0
16 changed files with 159 additions and 131 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2005, Waldemar Kornewald <Waldemar.Kornewald@web.de>
* Copyright 2003-2005, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
@ -77,7 +77,7 @@ PPPManager::~PPPManager()
net_remove_timer(fPulseTimer);
// now really delete the interfaces (the deleter_thread is not running)
ppp_interface_entry *entry;
ppp_interface_entry *entry = NULL;
for(int32 index = 0; index < fEntries.CountItems(); index++) {
entry = fEntries.ItemAt(index);
if(entry) {
@ -86,6 +86,16 @@ PPPManager::~PPPManager()
delete entry;
}
}
// also delete all ppp_up references
ppp_app_entry *app = NULL;
for(int32 index = 0; index < fApps.CountItems(); index++) {
app = fApps.ItemAt(index);
if(app) {
free(app->interfaceName);
delete entry;
}
}
}
@ -124,13 +134,13 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
return B_ERROR;
}
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
if(!entry->interface->DoesConnectOnDemand()
&& ifp->if_flags & (IFF_UP | IFF_RUNNING) != (IFF_UP | IFF_RUNNING)) {
m_freem(buf);
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return ENETDOWN;
}
@ -147,12 +157,12 @@ PPPManager::Output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
if(result == PPP_UNHANDLED)
continue;
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return result;
}
m_freem(buf);
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return B_ERROR;
}
@ -170,7 +180,7 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
}
int32 status = B_OK;
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
switch(cmd) {
@ -189,7 +199,7 @@ PPPManager::Control(ifnet *ifp, ulong cmd, caddr_t data)
status = entry->interface->StackControl(cmd, data);
}
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return status;
}
@ -233,7 +243,7 @@ PPPManager::DeleteInterface(ppp_interface_id ID)
// this check prevents a dead-lock
entry->deleting = true;
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
// bring interface down if needed
@ -241,7 +251,7 @@ PPPManager::DeleteInterface(ppp_interface_id ID)
|| entry->interface->Phase() != PPP_DOWN_PHASE)
entry->interface->Down();
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return true;
}
@ -398,11 +408,11 @@ PPPManager::Control(uint32 op, void *data, size_t length)
if(!entry || entry->deleting)
return B_BAD_INDEX;
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
entry->interface->Up();
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
} break;
case PPPC_BRING_INTERFACE_DOWN: {
@ -415,11 +425,11 @@ PPPManager::Control(uint32 op, void *data, size_t length)
if(!entry || entry->deleting)
return B_BAD_INDEX;
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
entry->interface->Down();
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
} break;
case PPPC_CONTROL_INTERFACE: {
@ -507,10 +517,10 @@ PPPManager::ControlInterface(ppp_interface_id ID, uint32 op, void *data, size_t
status_t result = B_BAD_INDEX;
ppp_interface_entry *entry = EntryFor(ID);
if(entry && !entry->deleting) {
atomic_add(entry->accessing, 1);
atomic_add(&entry->accessing, 1);
locker.UnlockNow();
result = entry->interface->Control(op, data, length);
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
}
return result;
@ -683,6 +693,23 @@ PPPManager::EntryFor(const driver_settings *settings) const
}
ppp_app_entry*
PPPManager::AppFor(const char *name) const
{
if(!name)
return NULL;
ppp_app_entry *app;
for(int32 index = 0; index < fApps.CountItems(); index++) {
app = fApps.ItemAt(index);
if(app && !strcmp(app->interfaceName, name))
return app;
}
return NULL;
}
void
PPPManager::SettingsChanged()
{
@ -748,7 +775,6 @@ PPPManager::_CreateInterface(const char *name,
entry->name = name ? strdup(name) : NULL;
entry->accessing = 1;
entry->deleting = false;
entry->requestThread = -1;
fEntries.AddItem(entry);
// nothing bad can happen because we are in a locked section
@ -763,13 +789,35 @@ PPPManager::_CreateInterface(const char *name,
return PPP_UNDEFINED_INTERFACE_ID;
}
// find an existing ppp_up entry or create a new one otherwise
if(entry->name) {
ppp_app_entry *app = AppFor(entry->name);
thread_info info;
if(!app || get_thread_info(app->thread, &info) != B_OK) {
if(!app) {
app = new ppp_app_entry;
app->interfaceName = strdup(entry->name);
fApps.AddItem(app);
}
// run new ppp_up instance
const char *argv[] = { "/boot/beos/bin/ppp_up", entry->name, NULL };
const char *env[] = { NULL };
app->thread = load_image(2, argv, env);
if(app->thread < 0)
ERROR("KPPPInterface::Up(): Error: could not load ppp_up!\n");
resume_thread(app->thread);
}
} else
entry->interface->SetAskBeforeConnecting(false);
locker.UnlockNow();
// it is safe to access the manager from userland now
if(!Report(PPP_MANAGER_REPORT, PPP_REPORT_INTERFACE_CREATED,
&id, sizeof(ppp_interface_id))) {
DeleteInterface(id);
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return PPP_UNDEFINED_INTERFACE_ID;
}
@ -777,7 +825,7 @@ PPPManager::_CreateInterface(const char *name,
entry->interface->StateMachine().DownProtocols();
entry->interface->StateMachine().ResetLCPHandlers();
atomic_add(entry->accessing, -1);
atomic_add(&entry->accessing, -1);
return id;
}
@ -841,6 +889,19 @@ PPPManager::DeleterThreadEvent()
delete entry;
}
}
// remove dead ppp_up entries
ppp_app_entry *app;
thread_info info;
for(int32 index = 0; index < fApps.CountItems(); index++) {
app = fApps.ItemAt(index);
if(app && get_thread_info(app->thread, &info) != B_OK) {
fApps.RemoveItem(index);
--index;
free(app->interfaceName);
delete app;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2005, Waldemar Kornewald <Waldemar.Kornewald@web.de>
* Copyright 2003-2005, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
@ -11,6 +11,13 @@
#include <core_funcs.h>
// used to identify a ppp_up instance
typedef struct ppp_app_entry {
char *interfaceName;
thread_id thread;
} ppp_app_entry;
// these functions are defined in ppp.cpp
extern int ppp_ifnet_stop(ifnet *ifp);
extern int ppp_ifnet_output(ifnet *ifp, struct mbuf *buf, struct sockaddr *dst,
@ -52,11 +59,13 @@ class PPPManager {
{ return ReportManager().Report(type, code, data, length); }
// returns false if reply was bad (or an error occured)
// these methods must be called from a locked section
ppp_interface_entry *EntryFor(ppp_interface_id ID,
int32 *saveIndex = NULL) const;
ppp_interface_entry *EntryFor(ifnet *ifp, int32 *saveIndex = NULL) const;
ppp_interface_entry *EntryFor(const char *name, int32 *saveIndex = NULL) const;
ppp_interface_entry *EntryFor(const driver_settings *settings) const;
ppp_app_entry *AppFor(const char *name) const;
void SettingsChanged();
@ -76,6 +85,7 @@ class PPPManager {
char *fDefaultInterface;
KPPPReportManager fReportManager;
TemplateList<ppp_interface_entry*> fEntries;
TemplateList<ppp_app_entry*> fApps;
ppp_interface_id fNextID;
thread_id fDeleterThread, fPulseTimer;
};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2005, Waldemar Kornewald <Waldemar.Kornewald@web.de>
* Copyright 2003-2005, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/

View File

@ -359,19 +359,18 @@ PAP::RREvent(struct mbuf *packet)
*peerPassword = (char*) passwordLength + 1;
const char *username = Interface().Username(), *password = Interface().Password();
if(*userLength == strlen(username) && *passwordLength == strlen(password)
&& !strncmp(peerUsername, username, *userLength)
&& !strncmp(peerPassword, password, *passwordLength)) {
NewState(ACCEPTED);
locker.UnlockNow();
Interface().StateMachine().PeerAuthenticationAccepted(user);
Interface().StateMachine().PeerAuthenticationAccepted(username);
UpEvent();
SendAck(packet);
} else {
NewState(INITIAL);
locker.UnlockNow();
Interface().StateMachine().PeerAuthenticationDenied(user);
Interface().StateMachine().PeerAuthenticationDenied(username);
UpFailedEvent();
SendNak(packet);
}

View File

@ -486,14 +486,7 @@ KPPPInterface::Control(uint32 op, void *data, size_t length)
if(length < sizeof(uint32) || !data)
return B_ERROR;
LockerHelper locker(fLock);
bool old = fAskBeforeConnecting;
fAskBeforeConnecting = *((uint32*)data);
if(old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
&& Phase() == PPP_DOWN_PHASE) {
locker.UnlockNow();
StateMachine().ContinueOpenEvent();
}
SetAskBeforeConnecting(*((uint32*)data));
break;
case PPPC_SET_MRU:
@ -974,6 +967,21 @@ KPPPInterface::SetConnectOnDemand(bool connectOnDemand = true)
}
//! Sets whether the user is asked before establishing the connection.
void
KPPPInterface::SetAskBeforeConnecting(bool ask)
{
LockerHelper locker(fLock);
bool old = fAskBeforeConnecting;
fAskBeforeConnecting = ask;
if(old && fAskBeforeConnecting == false && State() == PPP_STARTING_STATE
&& Phase() == PPP_DOWN_PHASE) {
locker.UnlockNow();
StateMachine().ContinueOpenEvent();
}
}
//! Sets Protocol-Field-Compression options.
bool
KPPPInterface::SetPFCOptions(uint8 pfcOptions)

View File

@ -64,7 +64,7 @@ KPPPReportManager::SendReport(thread_id thread, const ppp_report_packet *report)
report_sender_info *info = new report_sender_info;
info->thread = thread;
memcpy(&info->report, report, sizeof(ppp_report_packet));
resume_thread(spawn_thread(report_sender_thread, "PPP: ReportSender",
resume_thread(spawn_kernel_thread(report_sender_thread, "PPP: ReportSender",
B_NORMAL_PRIORITY, info));
return true;
}

View File

@ -765,7 +765,7 @@ KPPPStateMachine::OpenEvent()
case PPP_INITIAL_STATE:
fLastConnectionReportCode = PPP_REPORT_GOING_UP;
Interface().Report(PPP_CONNECTION_REPORT, PPP_REPORT_GOING_UP,
&fInterface.fID, sizeof(ppp_interface_id))
&fInterface.fID, sizeof(ppp_interface_id));
if(Interface().Mode() == PPP_SERVER_MODE) {
NewPhase(PPP_ESTABLISHMENT_PHASE);

View File

@ -157,6 +157,11 @@ class KPPPInterface : public KPPPLayer {
bool DoesConnectOnDemand() const
{ return fConnectOnDemand; }
void SetAskBeforeConnecting(bool ask);
//! Returns whether the user is asked before establishing the connection.
bool DoesAskBeforeConnecting() const
{ return fAskBeforeConnecting; }
//! Clients are in \c PPP_CLIENT_MODE and servers are in \c PPP_SERVER_MODE.
ppp_mode Mode() const
{ return fMode; }

View File

@ -108,6 +108,7 @@ class KPPPStateMachine {
// private events
void OpenEvent();
void ContinueOpenEvent();
void CloseEvent();
void TOGoodEvent();
void TOBadEvent();

View File

@ -73,9 +73,6 @@ PPPInterface::InitCheck() const
/*! \brief Changes the current interface.
The interface's info structure is cached in this object. If you want to update
its values you must call \c SetTo() again or use \c Control() with an op of
\c PPPC_GET_INTERFACE_INFO.\n
If this fails it will set the interface's \a ID to \c PPP_UNDEFINED_INTERFACE_ID.
\param ID The ID of the new interface.
@ -93,15 +90,17 @@ PPPInterface::SetTo(ppp_interface_id ID)
if(fFD < 0)
return B_ERROR;
fID = ID;
status_t error = Control(PPPC_GET_INTERFACE_INFO, &fInfo, sizeof(fInfo));
if(error != B_OK) {
memset(&fInfo, 0, sizeof(fInfo));
ppp_interface_info_t info;
if(GetInterfaceInfo(&info)) {
fName = info.info.name;
fID = ID;
} else {
fName = "";
fID = PPP_UNDEFINED_INTERFACE_ID;
return B_ERROR;
}
return error;
return B_OK;
}
@ -199,9 +198,7 @@ PPPInterface::GetSettingsEntry(BEntry *entry) const
}
/*! \brief Get the cached ppp_interface_info_t structure.
\param info The info structure is copied into this argument.
/*! \brief Get the ppp_interface_info_t structure.
\return \c true on success, \c false otherwise.
*/
@ -211,9 +208,8 @@ PPPInterface::GetInterfaceInfo(ppp_interface_info_t *info) const
if(InitCheck() != B_OK || !info)
return false;
memcpy(info, &fInfo, sizeof(fInfo));
return true;
return Control(PPPC_GET_INTERFACE_INFO, &info, sizeof(ppp_interface_info_t))
== B_OK;
}

View File

@ -147,8 +147,14 @@ PPPInterfaceListener::SetTarget(BHandler *target)
bool
PPPInterfaceListener::WatchInterface(ppp_interface_id ID)
{
if(ID == fInterface)
return true;
StopWatchingInterface();
if(ID == PPP_UNDEFINED_INTERFACE_ID)
return true;
// enable reports
PPPInterface interface(ID);
if(interface.InitCheck() != B_OK)

View File

@ -7,6 +7,7 @@
#define _PPP_INTERFACE__H
#include <KPPPManager.h>
#include <String.h>
class BEntry;
@ -21,7 +22,7 @@ class PPPInterface {
//! Returns the name of the interface description file.
const char *Name() const
{ return fInfo.info.name; }
{ return fName.String(); }
status_t SetTo(ppp_interface_id ID);
//! Returns the unique id of this interface.
@ -55,9 +56,8 @@ class PPPInterface {
private:
ppp_interface_id fID;
int fFD;
ppp_interface_info_t fInfo;
BString fName;
};

View File

@ -77,21 +77,10 @@ static const char *kErrorLoadingFailed = "Error: Failed loading interface! The "
static const char *kErrorSavingFailed = "Error: Failed saving interface settings!";
static
status_t
up_down_thread(void *data)
{
static_cast<DialUpView*>(data)->UpDownThread();
return B_OK;
}
DialUpView::DialUpView(BRect frame)
: BView(frame, "DialUpView", B_FOLLOW_NONE, 0),
fListener(this),
fUpDownThread(-1),
fCurrentItem(NULL),
fWatching(PPP_UNDEFINED_INTERFACE_ID),
fKeepLabel(false)
{
BRect bounds = Bounds();
@ -175,10 +164,9 @@ DialUpView::DialUpView(BRect frame)
DialUpView::~DialUpView()
{
fListener.StopWatchingInterface();
fListener.StopWatchingManager();
fSettings.SaveSettingsToFile();
int32 tmp;
wait_for_thread(fUpDownThread, &tmp);
}
@ -268,12 +256,10 @@ DialUpView::MessageReceived(BMessage *message)
} break;
case kMsgConnectButton: {
if(!fCurrentItem || fUpDownThread != -1)
if(!fCurrentItem)
return;
fUpDownThread = spawn_thread(up_down_thread, "up_down_thread",
B_NORMAL_PRIORITY, this);
resume_thread(fUpDownThread);
BringUpOrDown();
} break;
case kMsgUpdateDefaultInterface:
@ -287,7 +273,7 @@ DialUpView::MessageReceived(BMessage *message)
void
DialUpView::UpDownThread()
DialUpView::BringUpOrDown()
{
fSettings.SaveSettingsToFile();
BMessage settings;
@ -321,8 +307,6 @@ DialUpView::UpDownThread()
interface.Up();
} else
interface.Down();
fUpDownThread = -1;
}
@ -334,7 +318,8 @@ DialUpView::HandleReportMessage(BMessage *message)
ppp_interface_id id;
if(message->FindInt32("interface", reinterpret_cast<int32*>(&id)) != B_OK
|| (fWatching != PPP_UNDEFINED_INTERFACE_ID && id != fWatching))
|| (fListener.Interface() != PPP_UNDEFINED_INTERFACE_ID
&& id != fListener.Interface()))
return;
int32 type, code;
@ -343,27 +328,17 @@ DialUpView::HandleReportMessage(BMessage *message)
if(type == PPP_MANAGER_REPORT && code == PPP_REPORT_INTERFACE_CREATED) {
PPPInterface interface(id);
if(interface.InitCheck() != B_OK)
return;
ppp_interface_info_t info;
interface.GetInterfaceInfo(&info);
if(strcasecmp(info.info.name, fCurrentItem->Message()->FindString("name")))
if(interface.InitCheck() != B_OK
|| strcasecmp(interface.Name(),
fCurrentItem->Message()->FindString("name")))
return;
WatchInterface(id);
} else if(type == PPP_CONNECTION_REPORT) {
if(fWatching == PPP_UNDEFINED_INTERFACE_ID)
return;
} else if(type == PPP_CONNECTION_REPORT)
UpdateStatus(code);
} else if(type == PPP_DESTRUCTION_REPORT) {
if(fWatching == PPP_UNDEFINED_INTERFACE_ID)
return;
else if(type == PPP_DESTRUCTION_REPORT)
WatchInterface(fListener.Manager().InterfaceWithName(
fCurrentItem->Message()->FindString("name")));
}
}
@ -472,44 +447,12 @@ DialUpView::UpdateStatus(int32 code)
void
DialUpView::WatchInterface(ppp_interface_id ID)
{
// This method can be used to update the interface's connection status.
if(fWatching != ID) {
fListener.StopWatchingInterfaces();
if(ID == PPP_UNDEFINED_INTERFACE_ID || fListener.WatchInterface(ID))
fWatching = ID;
}
fListener.WatchInterface(ID);
// update status
PPPInterface interface(fWatching);
if(interface.InitCheck() != B_OK) {
PPPInterface interface(fListener.Interface());
if(interface.InitCheck() != B_OK)
UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL);
return;
}
ppp_interface_info_t info;
interface.GetInterfaceInfo(&info);
// transform phase into status
switch(info.info.phase) {
case PPP_DOWN_PHASE:
if(info.info.state == PPP_STARTING_STATE)
UpdateStatus(PPP_REPORT_GOING_UP);
else
UpdateStatus(PPP_REPORT_DOWN_SUCCESSFUL);
break;
case PPP_TERMINATION_PHASE:
break;
case PPP_ESTABLISHED_PHASE:
UpdateStatus(PPP_REPORT_UP_SUCCESSFUL);
break;
default:
UpdateStatus(PPP_REPORT_GOING_UP);
}
}

View File

@ -20,10 +20,10 @@ class DialUpView : public BView {
virtual void AttachedToWindow();
virtual void MessageReceived(BMessage *message);
void UpDownThread();
private:
void BringUpOrDown();
void HandleReportMessage(BMessage *message);
void CreateTabs();
@ -47,7 +47,6 @@ class DialUpView : public BView {
thread_id fUpDownThread;
BMenuItem *fCurrentItem, *fDeleterItem;
ppp_interface_id fWatching;
bool fKeepLabel;
BStringView *fStatusView;

View File

@ -177,7 +177,7 @@ GeneralAddon::LoadAuthenticationSettings()
// load username and password
BMessage parameter;
int32 parameterIndex = 0;
if(FindMessageParameter("Username", *fSettings, &parameter, &parameterIndex)
if(FindMessageParameter(PPP_USERNAME_KEY, *fSettings, &parameter, &parameterIndex)
&& parameter.FindString(MDSU_VALUES, &fUsername) == B_OK) {
hasUsername = true;
parameter.AddBool(MDSU_VALID, true);
@ -185,7 +185,7 @@ GeneralAddon::LoadAuthenticationSettings()
}
parameterIndex = 0;
if(FindMessageParameter("Password", *fSettings, &parameter, &parameterIndex)
if(FindMessageParameter(PPP_PASSWORD_KEY, *fSettings, &parameter, &parameterIndex)
&& parameter.FindString(MDSU_VALUES, &fPassword) == B_OK) {
fHasPassword = true;
parameter.AddBool(MDSU_VALID, true);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004, Waldemar Kornewald <wkornew@gmx.net>
* Copyright 2004-2005, Waldemar Kornewald <wkornew@gmx.net>
* Distributed under the terms of the MIT License.
*/
@ -19,7 +19,7 @@
BPoint
center_on_screen(BRect rect, BWindow *window = NULL)
{
BRect screenFrame = (BScreen(window).Frame());
BRect screenFrame = BScreen(window).Frame();
BPoint point((screenFrame.Width() - rect.Width()) / 2.0,
(screenFrame.Height() - rect.Height()) / 2.0);
if(!screenFrame.Contains(point))