wifidog 源码初分析(2)-转

上一篇分析了接入设备的首次浏览器访问请求如何通过 防火墙过滤规则 重定向到 wifidog 的 HTTP 服务中,本篇主要分析了 wifidog 在接收到 接入设备的 HTTP 访问请求后,如何将此 HTTP 请求重定向到 认证服务器(auth-server) 上。

通过上面的防火墙规则,会将通过上面的防火墙规则,会将HTTP请求的外部IP地址和端口通过NAT方式重定向至本地wifidog内嵌HTTP服务器的地址和端口上,并由内嵌HTTP服务器进行服务,而内嵌HTTP服务器的路径和回调处理如下:

[cpp] view plaincopy

  1. if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) {

  2. debug(LOG_ERR, "Could not create web server: %s", strerror(errno));  
  3. exit(1);  
  4. }  
  5. debug(LOG_DEBUG, "Assigning callbacks to web server");  
  6. httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog);  
  7. httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog);  
  8. httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about);  
  9. httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status);  
  10. httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth);  
  11. httpdAddC404Content(webserver, http_callback_404);

客户端首次访问时回调客户端首次访问时回调http_callback_404函数,在该函数中根据获取的客户端信息来配置重定向的URL fragment,如下:

[cpp] view plaincopy

  1. void

  2. http_callback_404(httpd *webserver, request *r)  
  3. {  
  4. char tmp_url[MAX_BUF],  
  5. *url,  
  6. *mac;  
  7. s_config    *config = config_get_config();  
  8. t_auth_serv *auth_server = get_auth_server();  
  9. memset(tmp_url, 0, sizeof(tmp_url));  
  10. /*
  11. * XXX Note the code below assumes that the client‘s request is a plain
  12. * http request to a standard port. At any rate, this handler is called only
  13. * if the internet/auth server is down so it‘s not a huge loss, but still.
  14. */ /* 用户需要访问的URL */
  15. snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",  
  16. r->request.host,  
  17. r->request.path,  
  18. r->request.query[0] ? "?" : "",  
  19. r->request.query);  
  20. url = httpdUrlEncode(tmp_url);  
  21. if (!is_online()) {  
  22. /* 路由器都接入不到 internet */
  23. char * buf;  
  24. send_http_page(r, "Uh oh! Internet access unavailable!", buf);  
  25. free(buf);  
  26. }  
  27. else if (!is_auth_online()) {  
  28. /* auth server 挂起 */
  29. char * buf;  
  30. send_http_page(r, "Uh oh! Login screen unavailable!", buf);  
  31. free(buf);  
  32. }  
  33. else {  
  34. /* 配置重定向到 auth server 的 url 参数 */
  35. char *urlFragment;  
  36. if (!(mac = arp_get(r->clientAddr))) {  
  37. /* We could not get their MAC address */
  38. debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request", r->clientAddr);  
  39. safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s",  
  40. auth_server->authserv_login_script_path_fragment,  
  41. config->gw_address,  
  42. config->gw_port,  
  43. config->gw_id,  
  44. url);  
  45. } else {            
  46. debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac);  
  47. safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s",  
  48. auth_server->authserv_login_script_path_fragment,  
  49. config->gw_address,  
  50. config->gw_port,  
  51. config->gw_id,  
  52. mac,  
  53. url);  
  54. }  
  55. /* 调用该函数将用户请求重定向到 auth server 的登录页面 */
  56. http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");  
  57. free(urlFragment);  
  58. }  
  59. free(url);  
  60. }

上面代码基本不用解释,具体重定向至auth server的消息在下面的 http_send_redirect_to_auth 函数中实现:

[cpp] view plaincopy

  1. void http_send_redirect_to_auth(request *r, char *urlFragment, char *text)

  2. {  
  3. char *protocol = NULL;  
  4. int port = 80;  
  5. t_auth_serv *auth_server = get_auth_server();  
  6. if (auth_server->authserv_use_ssl) {  
  7. protocol = "https";  
  8. port = auth_server->authserv_ssl_port;  
  9. } else {  
  10. protocol = "http";  
  11. port = auth_server->authserv_http_port;  
  12. }  
  13. char *url = NULL;

  14. safe_asprintf(&url, "%s://%s:%d%s%s",  
  15. protocol,  
  16. auth_server->authserv_hostname,  
  17. port,  
  18. auth_server->authserv_path,  
  19. urlFragment  
  20. );  
  21. http_send_redirect(r, url, text);  
  22. free(url);  
  23. }

具体的重定向URL给个实例:

POST /login/?gw_address=192.168.1.1&gw_port=2060&gw_id=default&mac=44:94:fc:ef:28:40&url=http%3A//www.baidu.com/ HTTP/1.1

可以看到这里有这几个参数信息:

2gw_address,路由器的LAN地址

2gw_port:为wifidog的监听端口

2gw_id:路由器的标识名

2mac:客户端设备的MAC地址

2url:为客户端访问的原URL(以便于重定向)

wifidog 源码初分析(2)-转

时间: 2024-11-08 02:15:24

wifidog 源码初分析(2)-转的相关文章

wifidog 源码初分析(4)-转

在上一篇<wifidog 源码处分析(3)>的流程结束后,接入设备的浏览器重定向至 路由器 上 wifidog 的 http 服务(端口 2060) /wifidog/auth 上(且携带了 认证服务器 为此接入设备分配的 token),本篇就是从 wifidog 接收到 /wifidog/auth 的访问后的 校验流程. - 根据<wifidog 源码初分析(2)>中描述的,在 wifidog 启动 http 服务前,注册了一个针对访问路径 /wifidog/auth 的回调,如

wifidog 源码初分析(1)-转

wifidog 的核心还是依赖于 iptables 防火墙过滤规则来实现的,所以建议对 iptables 有了了解后再去阅读 wifidog 的源码. 在路由器上启动 wifidog 之后,wifidog 在启动时会初始化一堆的防火墙规则,如下: [cpp] view plaincopy /** Initialize the firewall rules */ int iptables_fw_init(void)   {   - -   /* * * Everything in the NAT

wifidog 源码初分析(3)-转

上一篇分析了 接入设备 在接入路由器,并发起首次 HTTP/80 请求到路由器上时,wifidog 是如何将此 HTTP 请求重定向至 auth-server 的流程. 之后 接入设备 的浏览器接收到 wifidog 返回的 302 重定向请求后,会将页面重定向至 auth-server 的 /login 页面,并且在此 URL 中会携带一些 路由器/网关 参数,以及 接入设备的 MAC 地址 和 客户端访问的源URL(如示例中的 baidu.com). 下面几个步骤就是 接入设备 到 auth

Hadoop学习笔记(9) ——源码初窥

Hadoop学习笔记(9) ——源码初窥 之前我们把Hadoop算是入了门,下载的源码,写了HelloWorld,简要分析了其编程要点,然后也编了个较复杂的示例.接下来其实就有两条路可走了,一条是继续深入研究其编程及部署等,让其功能使用的淋漓尽致.二是停下来,先看看其源码,研究下如何实现的.在这里我就选择第二条路. 研究源码,那我们就来先看一下整个目录里有点啥: 这个是刚下完代码后,目录列表中的内容. 目录/文件 说明 bin 下面存放着可执行的sh命名,所有操作都在这里 conf 配置文件所在

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的.对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug. sorry,废话多了.首先给个思路: 1.使opencv 的hi

uboot移植——uboot源码目录分析

uboot移植(一)--uboot源码目录分析 本文分析的uboot是九鼎官方提供的,是对应s5pv210开发板x210bv3的uboot 一:uboot的概念及移植的原理. uboot就是在内核运行前的一段小程序,用来初始化硬件设备,建立内存空间映射图.从而将系统的软硬件带到合适的状态,主要功能就是为了启动内核,它将内核从flash中拷贝到ddr中,然后跳转到内核入口中,交由内核控制权,uboot严重依赖硬件,因此一个通用的uboot不太可能. 移植原理:uboot中有很多平行代码,各自属于各

netty 源码简单分析一

周末简单看了下netty5的源码,只看懂了个大概,记录下成果,方便下次再看的时候回忆. 上服务端代码: public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.grou

MapReduce job在JobTracker初始化源码级分析

mapreduce job提交流程源码级分析(三)中已经说明用户最终调用JobTracker.submitJob方法来向JobTracker提交作业.而这个方法的核心提交方法是JobTracker.addJob(JobID jobId, JobInProgress job)方法,这个addJob方法会把Job提交到调度器(默认是JobQueueTaskScheduler)的监听器JobQueueJobInProgressListener和EagerTaskInitializationListen

OpenStack_Swift源码分析——创建Ring及添加设备源码详细分析

1 创建Ring 代码详细分析 在OpenStack_Swift--Ring组织架构中我们详细分析了Ring的具体工作过程,下面就Ring中增加设备,删除设备,已经重新平衡的实现过程作详细的介绍. 首先看RingBuilder类 def __init__(self, part_power, replicas, min_part_hours): #why 最大 2**32 if part_power > 32: raise ValueError("part_power must be at