简体   繁体   English

在应用程序崩溃时未删除Unix域套接字文件

[英]Unix domain socket file not removed on application crash

I have a Linux C++ application which spawns and interact with another process through Unix Domain Socket. 我有一个Linux C ++应用程序,该应用程序通过Unix Domain Socket生成并与另一个进程交互。 This new process basically just displays an icon of the process being currently runnning in the taskbar with some menu items displayed in the icon. 这个新进程基本上只在任务栏中显示当前正在运行的进程的图标,并在该图标中显示一些菜单项。

Problem: When main application is closed gracefully the UDS file is removed. 问题:正常关闭主应用程序后,将删除UDS文件。 But in case of an application crash, this UDS file is not removed and it lingers. 但是,如果应用程序崩溃,则不会删除此UDS文件,并且该文件会持续存在。

Is there any way of removing the UDS file upon application crash through coding? 有什么方法可以在应用程序崩溃时通过编码删除UDS文件?

Is there any way of removing the UDS file upon application crash through coding? 有什么方法可以在应用程序崩溃时通过编码删除UDS文件?

Yes. 是。 Several ways depending on how okay you are with using potentially non portable capabilities or not. 有几种方法取决于您使用潜在的非便携式功能的能力。

Using a separate process: 使用单独的过程:

Use a separate process to monitor your application; 使用单独的过程来监视您的应用程序; perhaps one you've written for this purpose. 也许是您为此目的而写的。 When this monitoring process detects that your application has ended, it checks for the Unix domain socket file. 当此监视过程检测到您的应用程序已结束时,它将检查Unix域套接字文件。 If found, it deletes it. 如果找到,它将删除它。 It then restarts the application (if needed). 然后重新启动应用程序(如果需要)。

Using "abstract socket": 使用“抽象套接字”:

I believe you can also use an "abstract socket", though I have not tried this myself. 我相信您也可以使用“抽象套接字”,尽管我自己还没有尝试过。

An online linux manual page for the Unix domain socket describes an extension called "abstract sockets". 用于Unix域套接字的在线linux手册页描述了称为“抽象套接字”的扩展。 It explains that: "Abstract sockets automatically disappear when all open references to the socket are closed.". 它解释说:“当关闭所有对套接字的打开的引用时,抽象套接字会自动消失。”

Using "close-behind semantics": 使用“封闭式语义”:

A Linux-based Unix domain socket manual page notes section claims: "The usual UNIX close-behind semantics apply; the socket can be unlinked at any time and will be finally removed from the filesystem when the last reference to it is closed". 基于Linux的Unix域套接字手册页的注释部分声称:“通常的UNIX封闭式语义适用;该套接字可以随时取消链接,并且在最后一次关闭对它的引用时,它将最终从文件系统中删除”。 Ie call bind to create the socket, wait till the client has connected, then unlink the socket, then go about with the code that might crash. 即调用bind来创建套接字,等到客户端连接后,再unlink套接字的unlink ,然后处理可能会崩溃的代码。 Once the socket is removed from the directory entry however, new client connection attempts will fail. 但是,一旦从目录条目中删除套接字,新的客户端连接尝试将失败。

Using a potential workaround 使用潜在的解决方法

Use SO_REUSEADDR on your socket before your bind call. bind调用之前,请在套接字上使用SO_REUSEADDR This may allow the application to restart without needing to delete the socket. 这可能允许应用程序重新启动而无需删除套接字。 I do not know if this behavior is well defined though for Unix sockets. 我不知道这种行为是否为Unix套接字定义得很好。 It may work on one platform but not another. 它可能在一个平台上运行,但在另一个平台上不运行。

Problem: When main application is closed gracefully the UDS file is removed. 问题:正常关闭主应用程序后,将删除UDS文件。 But in case of an application crash, this UDS file is not removed and it lingers. 但是,如果应用程序崩溃,则不会删除此UDS文件,并且该文件会持续存在。

Another way to handle the Unix domain socket file (the portable/standard version of it) is to delete the socket file in your application before it goes about creating it. 处理Unix域套接字文件(它的可移植/标准版本)的另一种方法是在创建应用程序之前删除应用程序中的套接字文件。 So before your application calls bind , it would use unlink . 因此,在您的应用程序调用bind之前,它将使用unlink So long as it's the sole process that would be creating this file, things should be copacetic wrt avoiding races. 只要这是创建此文件的唯一过程,就应该避免发生种族冲突。

Beware though that using unlink could open a potential security vulnerability if your application runs with heightened privileges (for instance using the set-user-ID capability to run as say root). 但是请注意,如果您的应用程序以更高的特权运行(例如,使用set-user-ID功能以root身份运行),则使用unlink可能会打开潜在的安全漏洞。 Make sure then that the user cannot tell the application what path to use for the socket and that none of the directories wherein the socket will reside is modifiable by the user. 然后,请确保用户无法告诉应用程序用于套接字的路径,并且该套接字所在的目录都不能由用户修改。 Otherwise, a user could tell the application that the socket's full path was something like /etc/passwd and run it to have that file deleted even though the user them self would not have had the privilege to do it. 否则,用户可以告诉应用程序套接字的完整路径类似于/etc/passwd然后运行它以删除该文件,即使他们自己的用户没有权限执行该操作。

This potential for damage is of course mitigated by things like using a least-privileged account for a set-user-ID privilege or by avoiding set-user-ID all together. 当然,可以通过使用最少特权帐户来获得设置用户ID特权或一起避免设置用户ID来减轻这种损坏的可能性。 Another mitigation would be to not allow the user to instruct the application what path to use for its socket - like perhaps by just using a hard-coded pathname for which the user would have no write privileges to any of its directories. 另一个缓解措施是不允许用户指示应用程序为其套接字使用什么路径-可能仅使用硬编码的路径名,而该用户对该用户的任何目录都没有写权限,这可能是一个缓解方法。

Not sure if that helps, but you can detect and orphaned unix socket. 不确定是否有帮助,但是您可以检测到孤立的unix套接字。

You can try locking a file or the socket on start-up. 您可以尝试在启动时锁定文件或套接字。 If the lock succeeds that means the socket is orphaned and can be removed. 如果锁定成功,则意味着该套接字是孤立的并且可以删除。 This is because file locks are released by the OS when a process is terminated for any reason. 这是因为由于任何原因终止进程时,操作系统都会释放文件锁。

Alternatively, bind to that unix socket. 或者, bind到该unix套接字。 bind succeeds only if the socket name is unused. 仅当套接字名称未使用时, bind才会成功。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM